Topic: Status of Expected proposal (Parsing Numbers)


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 20 May 2015 17:08:52 +0200
Raw View
This is a multi-part message in MIME format.
--------------040507080707090305010801
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
> On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:
>
>     On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas <jmck...@gmail.com
>     <javascript:>> wrote:
>     > I just want to see the "sto*" functions get string_view ASAP. We
>     shouldn't
>     > wait on `expected` just to accomplish that.
>
>     That seems like a straightforward paper to get through the committee.
>     If you write it, I'll try to prevent the group from creeping its
>     scope.
>
>
> Actually, that paper already exists (N4015=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>),=20
> with a revision (N4109=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>).=20
> According to Vicente Escriba, who both wrote those proposals and=20
> replied here, scope creep has already started. Also, N4109 has been a=20
> while ago (almost a year now), with no followup paper from any=20
> discussions based on it.
>
Yes its me. There is an error on the web page that I have already=20
reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt=20
name and Botet Escriba is my last name.

The expected proposal was blocked as the expected proposal was proposing=20
an alternative way to report errors and the standard C++ has already=20
one: exceptions. A study of all the alternative ways to reporting errors=20
was requested so we can take a decision on which ones could be used once=20
the advantages and liabilities of each approach are detailed. I'm not a=20
paper writer and writing such a paper needs to be done carefully and it=20
would takes time. If there are any volunteers to write it, please do it,=20
it will be a pleasure to help. Of course, I will be very happy is this=20
paper unblocks the expected proposal.
> I think at this point, we should focus on getting the core feature:=20
> parsing strings via string_view. And those many malign the FileSystem=20
> TS solution, it /is/ prior art on dealing with error codes in standard=20
> library C++.
>
I don't share the FileSystem design to report errors. I have used it in=20
Boost.Chrono, and it really doesn't scale. It is difficult to say it is=20
prior art when we include it in the FS TS. For me, it is the temporary=20
C++ standard way of defining interfaces that report errors without using=20
exceptions until we have a better way.

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/.

--------------040507080707090305010801
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 19/05/15 03:01, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:49314809-5bb3-4e49-8cb4-efa78b9ee67d@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM UTC-4,
        Jeffrey Yasskin wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Mon,
          May 18, 2015 at 2:57 PM, Nicol Bolas &lt;<a
            moz-do-not-send=3D"true" href=3D"javascript:" target=3D"_blank"
            gdf-obfuscated-mailto=3D"D4FBlv7Hr1AJ" rel=3D"nofollow"
            onmousedown=3D"this.href=3D'javascript:';return true;"
            onclick=3D"this.href=3D'javascript:';return true;">jmck...@gmai=
l.com</a>&gt;

          wrote: <br>
          &gt; I just want to see the "sto*" functions get string_view
          ASAP. We shouldn't <br>
          &gt; wait on `expected` just to accomplish that. <br>
          <br>
          That seems like a straightforward paper to get through the
          committee. <br>
          If you write it, I'll try to prevent the group from creeping
          its <br>
          scope. <br>
        </blockquote>
        <div><br>
          Actually, that paper already exists (<a moz-do-not-send=3D"true"
href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf">=
N4015</a>),

          with a revision (<a moz-do-not-send=3D"true"
            href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014=
/n4109.pdf">N4109</a>).


          According to Vicente Escriba, who both wrote those proposals
          and replied here, scope creep has already started. Also, N4109
          has been a while ago (almost a year now), with no followup
          paper from any discussions based on it.<br>
          <br>
        </div>
      </div>
    </blockquote>
    Yes its me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I'm not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br>
    <blockquote
      cite=3D"mid:49314809-5bb3-4e49-8cb4-efa78b9ee67d@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>I think at this point, we should focus on getting the core
          feature: parsing strings via string_view. And those many
          malign the FileSystem TS solution, it <i>is</i> prior art on
          dealing with error codes in standard library C++.<br>
        </div>
      </div>
      <br>
    </blockquote>
    I don't share the FileSystem design to report errors. I have used it
    in Boost.Chrono, and it really doesn't scale. It is difficult to say
    it is prior art when we include it in the FS TS. For me, it is the
    temporary C++ standard way of defining interfaces that report errors
    without using exceptions until we have a better way.<br>
    <br>
    Vicente<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 />

--------------040507080707090305010801--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 20 May 2015 14:05:28 -0400
Raw View
--001a11c3f56ca9cc8005168745a5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, May 20, 2015 at 11:08 AM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:

>  Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>
> On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:
>>
>> On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>> > I just want to see the "sto*" functions get string_view ASAP. We
>> shouldn't
>> > wait on `expected` just to accomplish that.
>>
>> That seems like a straightforward paper to get through the committee.
>> If you write it, I'll try to prevent the group from creeping its
>> scope.
>>
>
> Actually, that paper already exists (N4015
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>),
> with a revision (N4109
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>).
> According to Vicente Escriba, who both wrote those proposals and replied
> here, scope creep has already started. Also, N4109 has been a while ago
> (almost a year now), with no followup paper from any discussions based on
> it.
>
>   Yes its me. There is an error on the web page that I have already
> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt nam=
e
> and Botet Escriba is my last name.
>
> The expected proposal was blocked as the expected proposal was proposing
> an alternative way to report errors and the standard C++ has already one:
> exceptions. A study of all the alternative ways to reporting errors was
> requested so we can take a decision on which ones could be used once the
> advantages and liabilities of each approach are detailed. I'm not a paper
> writer and writing such a paper needs to be done carefully and it would
> takes time. If there are any volunteers to write it, please do it, it wil=
l
> be a pleasure to help. Of course, I will be very happy is this paper
> unblocks the expected proposal.
>
>  I think at this point, we should focus on getting the core feature:
> parsing strings via string_view. And those many malign the FileSystem TS
> solution, it *is* prior art on dealing with error codes in standard
> library C++.
>
>  I don't share the FileSystem design to report errors. I have used it in
> Boost.Chrono, and it really doesn't scale. It is difficult to say it is
> prior art when we include it in the FS TS. For me, it is the temporary C+=
+
> standard way of defining interfaces that report errors without using
> exceptions until we have a better way.
>
> Vicente
>


Yes I really think we should use FS as an example of "there must be a
better way to do this".  To me that is either:

- just use exceptions
or
- something like expected<>

The FS should have half as many functions as it currently has.  I hope that
is fixed before standardization.

Tony



>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=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/.

--001a11c3f56ca9cc8005168745a5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, May 20, 2015 at 11:08 AM, Vicente J. Botet Escriba <span dir=3D=
"ltr">&lt;<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vic=
ente.botet@wanadoo.fr</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>Le 19/05/15 03:01, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM UTC-4,
        Jeffrey Yasskin wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">On Mon,
          May 18, 2015 at 2:57 PM, Nicol Bolas &lt;<a rel=3D"nofollow">jmck=
....@gmail.com</a>&gt;

          wrote: <br>
          &gt; I just want to see the &quot;sto*&quot; functions get string=
_view
          ASAP. We shouldn&#39;t <br>
          &gt; wait on `expected` just to accomplish that. <br>
          <br>
          That seems like a straightforward paper to get through the
          committee. <br>
          If you write it, I&#39;ll try to prevent the group from creeping
          its <br>
          scope. <br>
        </blockquote>
        <div><br>
          Actually, that paper already exists (<a href=3D"http://www.open-s=
td.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf" target=3D"_blank">N4015</=
a>),

          with a revision (<a href=3D"http://www.open-std.org/JTC1/SC22/WG2=
1/docs/papers/2014/n4109.pdf" target=3D"_blank">N4109</a>).


          According to Vicente Escriba, who both wrote those proposals
          and replied here, scope creep has already started. Also, N4109
          has been a while ago (almost a year now), with no followup
          paper from any discussions based on it.<br>
          <br>
        </div>
      </div>
    </blockquote>
    Yes its me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I&#39;m not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>I think at this point, we should focus on getting the core
          feature: parsing strings via string_view. And those many
          malign the FileSystem TS solution, it <i>is</i> prior art on
          dealing with error codes in standard library C++.<br>
        </div>
      </div>
      <br>
    </blockquote>
    I don&#39;t share the FileSystem design to report errors. I have used i=
t
    in Boost.Chrono, and it really doesn&#39;t scale. It is difficult to sa=
y
    it is prior art when we include it in the FS TS. For me, it is the
    temporary C++ standard way of defining interfaces that report errors
    without using exceptions until we have a better way.<span class=3D"HOEn=
Zb"><font color=3D"#888888"><br>
    <br>
    Vicente<br></font></span></div></blockquote><div><br><br></div><div>Yes=
 I really think we should use FS as an example of &quot;there must be a bet=
ter way to do this&quot;.=C2=A0 To me that is either:<br><br></div><div>- j=
ust use exceptions<br></div><div>or<br></div><div>- something like expected=
&lt;&gt;<br><br></div><div>The FS should have half as many functions as it =
currently has.=C2=A0 I hope that is fixed before standardization.<br><br></=
div><div>Tony<br><br>=C2=A0<br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div te=
xt=3D"#000000" bgcolor=3D"#FFFFFF"><span class=3D"HOEnZb"><font color=3D"#8=
88888">
  </font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">


<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div></div>

<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 />

--001a11c3f56ca9cc8005168745a5--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 May 2015 11:09:20 -0700 (PDT)
Raw View
------=_Part_4495_1740877310.1432145360784
Content-Type: multipart/alternative;
 boundary="----=_Part_4496_1607742442.1432145360785"

------=_Part_4496_1607742442.1432145360785
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, May 20, 2015 at 2:05:31 PM UTC-4, Tony V E wrote:
>
> On Wed, May 20, 2015 at 11:08 AM, Vicente J. Botet Escriba <
> vicent...@wanadoo.fr <javascript:>> wrote:
>
>>  Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>> =20
>> On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:=20
>>>
>>> On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas <jmck...@gmail.com> wrote:=
=20
>>> > I just want to see the "sto*" functions get string_view ASAP. We=20
>>> shouldn't=20
>>> > wait on `expected` just to accomplish that.=20
>>>
>>> That seems like a straightforward paper to get through the committee.=
=20
>>> If you write it, I'll try to prevent the group from creeping its=20
>>> scope.=20
>>>
>>
>> Actually, that paper already exists (N4015=20
>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>),=20
>> with a revision (N4109=20
>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>).=20
>> According to Vicente Escriba, who both wrote those proposals and replied=
=20
>> here, scope creep has already started. Also, N4109 has been a while ago=
=20
>> (almost a year now), with no followup paper from any discussions based o=
n=20
>> it.
>>
>>   Yes its me. There is an error on the web page that I have already=20
>> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt na=
me=20
>> and Botet Escriba is my last name.=20
>>
>> The expected proposal was blocked as the expected proposal was proposing=
=20
>> an alternative way to report errors and the standard C++ has already one=
:=20
>> exceptions. A study of all the alternative ways to reporting errors was=
=20
>> requested so we can take a decision on which ones could be used once the=
=20
>> advantages and liabilities of each approach are detailed. I'm not a pape=
r=20
>> writer and writing such a paper needs to be done carefully and it would=
=20
>> takes time. If there are any volunteers to write it, please do it, it wi=
ll=20
>> be a pleasure to help. Of course, I will be very happy is this paper=20
>> unblocks the expected proposal.
>>
>>  I think at this point, we should focus on getting the core feature:=20
>> parsing strings via string_view. And those many malign the FileSystem TS=
=20
>> solution, it *is* prior art on dealing with error codes in standard=20
>> library C++.
>> =20
>>  I don't share the FileSystem design to report errors. I have used it in=
=20
>> Boost.Chrono, and it really doesn't scale. It is difficult to say it is=
=20
>> prior art when we include it in the FS TS. For me, it is the temporary C=
++=20
>> standard way of defining interfaces that report errors without using=20
>> exceptions until we have a better way.
>>
>> Vicente
>>
>
>
> Yes I really think we should use FS as an example of "there must be a=20
> better way to do this".  To me that is either:
>
> - just use exceptions
> or
> - something like expected<>
>
> The FS should have half as many functions as it currently has.  I hope=20
> that is fixed before standardization.
>

I personally have no complaints about the filesystem's method of doing=20
error codes. But I also wouldn't be adverse to seeing `expected` used=20
instead of error code parameter outputs.

But one thing I'm adamantly against is being forced to use error codes.=20
They should be *optional*, not mandatory. In C++, exceptions are the=20
standard way of signaling errors; I shouldn't have to deal with error codes=
=20
unless I choose to.

So I would say that filesystem should keep the same number of functions.=20
Either that, or it shouldn't support error codes at all.

--=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/.

------=_Part_4496_1607742442.1432145360785
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 20, 2015 at 2:05:31 PM UTC-4, Tony V E w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><di=
v class=3D"gmail_quote">On Wed, May 20, 2015 at 11:08 AM, Vicente J. Botet =
Escriba <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"NrolvPzEMuEJ" rel=3D"nofollow" onmousedown=3D"this.hr=
ef=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';retur=
n true;">vicent...@wanadoo.fr</a>&gt;</span> wrote:<br><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>Le 19/05/15 03:01, Nicol Bolas a
      =C3=A9crit&nbsp;:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM UTC-4,
        Jeffrey Yasskin wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">On Mon,
          May 18, 2015 at 2:57 PM, Nicol Bolas &lt;<a rel=3D"nofollow">jmck=
....@gmail.com</a>&gt;

          wrote: <br>
          &gt; I just want to see the "sto*" functions get string_view
          ASAP. We shouldn't <br>
          &gt; wait on `expected` just to accomplish that. <br>
          <br>
          That seems like a straightforward paper to get through the
          committee. <br>
          If you write it, I'll try to prevent the group from creeping
          its <br>
          scope. <br>
        </blockquote>
        <div><br>
          Actually, that paper already exists (<a href=3D"http://www.open-s=
td.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf" target=3D"_blank" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A=
%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4015.=
pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';return=
 true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2F=
www.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4015.pdf\46=
sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';return true;=
">N4015</a>),

          with a revision (<a href=3D"http://www.open-std.org/JTC1/SC22/WG2=
1/docs/papers/2014/n4109.pdf" target=3D"_blank" rel=3D"nofollow" onmousedow=
n=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.o=
rg%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa\75D\46sntz\=
0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2FJ=
TC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;">N4109</a>).


          According to Vicente Escriba, who both wrote those proposals
          and replied here, scope creep has already started. Also, N4109
          has been a while ago (almost a year now), with no followup
          paper from any discussions based on it.<br>
          <br>
        </div>
      </div>
    </blockquote>
    Yes its me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I'm not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>I think at this point, we should focus on getting the core
          feature: parsing strings via string_view. And those many
          malign the FileSystem TS solution, it <i>is</i> prior art on
          dealing with error codes in standard library C++.<br>
        </div>
      </div>
      <br>
    </blockquote>
    I don't share the FileSystem design to report errors. I have used it
    in Boost.Chrono, and it really doesn't scale. It is difficult to say
    it is prior art when we include it in the FS TS. For me, it is the
    temporary C++ standard way of defining interfaces that report errors
    without using exceptions until we have a better way.<span><font color=
=3D"#888888"><br>
    <br>
    Vicente<br></font></span></div></blockquote><div><br><br></div><div>Yes=
 I really think we should use FS as an example of "there must be a better w=
ay to do this".&nbsp; To me that is either:<br><br></div><div>- just use ex=
ceptions<br></div><div>or<br></div><div>- something like expected&lt;&gt;<b=
r><br></div><div>The FS should have half as many functions as it currently =
has.&nbsp; I hope that is fixed before standardization.<br></div></div></di=
v></div></blockquote><div><br>I personally have no complaints about the fil=
esystem's method of doing error codes. But I also wouldn't be adverse to se=
eing `expected` used instead of error code parameter outputs.<br><br>But on=
e thing I'm adamantly against is being forced to use error codes. They shou=
ld be <i>optional</i>, not mandatory. In C++, exceptions are the standard w=
ay of signaling errors; I shouldn't have to deal with error codes unless I =
choose to.<br><br>So I would say that filesystem should keep the same numbe=
r of functions. Either that, or it shouldn't support error codes at all.<br=
></div></div>

<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 />

------=_Part_4496_1607742442.1432145360785--
------=_Part_4495_1740877310.1432145360784--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 20 May 2015 11:29:42 -0700
Raw View
On Wednesday 20 May 2015 11:09:20 Nicol Bolas wrote:
> But one thing I'm adamantly against is being forced to use error codes.
> They should be *optional*, not mandatory. In C++, exceptions are the
> standard way of signaling errors; I shouldn't have to deal with error codes
> unless I choose to.

True, and on the other hand I'm hoping that the committee realises that
there's a world without exceptions. There are many environments where
exceptions cannot be used and it's irrelevant whether those reasons are good
or bad. Making APIs that work for those environments increases their use-base.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 20 May 2015 11:49:59 -0700 (PDT)
Raw View
------=_Part_900_1090505045.1432147799222
Content-Type: multipart/alternative;
 boundary="----=_Part_901_1492847817.1432147799222"

------=_Part_901_1492847817.1432147799222
Content-Type: text/plain; charset=UTF-8


>
> On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba
> wrote:
> Yes its me. There is an error on the web page that I have already
> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt name
> and Botet Escriba is my last name.
>
> The expected proposal was blocked as the expected proposal was proposing
> an alternative way to report errors and the standard C++ has already one:
> exceptions. A study of all the alternative ways to reporting errors was
> requested so we can take a decision on which ones could be used once the
> advantages and liabilities of each approach are detailed. I'm not a paper
> writer and writing such a paper needs to be done carefully and it would
> takes time. If there are any volunteers to write it, please do it, it will
> be a pleasure to help. Of course, I will be very happy is this paper
> unblocks the expected proposal.
>

The string_view to int paper could be a good candidate for such a study.

On Wednesday, May 20, 2015 at 2:29:47 PM UTC-4, Thiago Macieira wrote:
>
> On Wednesday 20 May 2015 11:09:20 Nicol Bolas wrote:
> > But one thing I'm adamantly against is being forced to use error codes.
> > They should be *optional*, not mandatory. In C++, exceptions are the
> > standard way of signaling errors; I shouldn't have to deal with error
> codes
> > unless I choose to.
>
> True, and on the other hand I'm hoping that the committee realises that
> there's a world without exceptions. There are many environments where
> exceptions cannot be used and it's irrelevant whether those reasons are
> good
> or bad. Making APIs that work for those environments increases their
> use-base.
>

I agree with Thiago.

Unfortunately, exceptions cannot be the standard C++ way. There needs to be
an exception way and a non-exception way. Maybe its kind of ugly to have to
support both but that is the reality.

The big problem with exceptions is that if you do not carefully handle
every possible exception an interface can throw your application will
crash. Even worse, many of these exceptions only occur for exceptional
scenarios which are very hard and expensive (in programmer time) to fully
cover in unit tests. If you turn on exceptions, you can never be quite sure
there isn't some edge case out there that will throw and crash your whole
program.

A good example of this is the cppformat library which is a modern printf
replacement. This library throws exceptions if you don't match the number
of parameters with the number of "{}" in your format string. The first
thing I did was disable exceptions here. Imagine your entire system
crashing just because someone forgot to format a log message correctly?
I've been in plenty of environments where a crash at the wrong time in
production could result in huge unrecoverable losses.

I like expected because it pushes the question of exception handling onto
the client without needing duplicate exception and non-exception
interfaces. If the client checks the error status of expected his
application will never throw and the optimizer can even remove all of the
throwing code and consider the function body functionally noexcept.

I imagine implementations could even produce a warning such that when
-fnoexceptions is enabled it will warn whenever an expected object value is
referenced without checking the error condition first. That would go a long
way in helping programmers handle errors.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_901_1492847817.1432147799222
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">=
On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba w=
rote:<br>Yes its me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I'm not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br></blockquote><div><br>The string_view to int pape=
r could be a good candidate for such a study.<br></div><br>On Wednesday, Ma=
y 20, 2015 at 2:29:47 PM UTC-4, Thiago Macieira wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;">On Wednesday 20 May 2015 11:09:20 Nicol Bolas wrote=
:
<br>&gt; But one thing I'm adamantly against is being forced to use error c=
odes.=20
<br>&gt; They should be *optional*, not mandatory. In C++, exceptions are t=
he=20
<br>&gt; standard way of signaling errors; I shouldn't have to deal with er=
ror codes=20
<br>&gt; unless I choose to.
<br>
<br>True, and on the other hand I'm hoping that the committee realises that=
=20
<br>there's a world without exceptions. There are many environments where=
=20
<br>exceptions cannot be used and it's irrelevant whether those reasons are=
 good=20
<br>or bad. Making APIs that work for those environments increases their us=
e-base.
<br></blockquote><div><br>I agree with Thiago.<br><br>Unfortunately, except=
ions cannot be the standard C++ way. There needs to be an exception way and=
 a non-exception way. Maybe its kind of ugly to have to support both but th=
at is the reality.<br><br>The big problem with exceptions is that if you do=
 not carefully handle every possible exception an interface can throw your =
application will crash. Even worse, many of these exceptions only occur for=
 exceptional scenarios which are very hard and expensive (in programmer tim=
e) to fully cover in unit tests. If you turn on exceptions, you can never b=
e quite sure there isn't some edge case out there that will throw and crash=
 your whole program.<br><br>A good example of this is the cppformat library=
 which is a modern printf replacement. This library throws exceptions if yo=
u don't match the number of parameters with the number of "{}" in your form=
at string. The first thing I did was disable exceptions here. Imagine your =
entire system crashing just because someone forgot to format a log message =
correctly? I've been in plenty of environments where a crash at the wrong t=
ime in production could result in huge unrecoverable losses.<br><br>I like =
expected because it pushes the question of exception handling onto the clie=
nt without needing duplicate exception and non-exception interfaces. If the=
 client checks the error status of expected his application will never thro=
w and the optimizer can even remove all of the throwing code and consider t=
he function body functionally noexcept. <br><br>I imagine implementations c=
ould even produce a warning such that when -fnoexceptions is enabled it wil=
l warn whenever an expected object value is referenced without checking the=
 error condition first. That would go a long way in helping programmers han=
dle errors.<br>&nbsp;</div></div>

<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 />

------=_Part_901_1492847817.1432147799222--
------=_Part_900_1090505045.1432147799222--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 May 2015 12:02:03 -0700 (PDT)
Raw View
------=_Part_1121_294283598.1432148523711
Content-Type: multipart/alternative;
 boundary="----=_Part_1122_369592545.1432148523711"

------=_Part_1122_369592545.1432148523711
Content-Type: text/plain; charset=UTF-8



On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:
>
> On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba
>> wrote:
>> Yes its me. There is an error on the web page that I have already
>> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt name
>> and Botet Escriba is my last name.
>>
>> The expected proposal was blocked as the expected proposal was proposing
>> an alternative way to report errors and the standard C++ has already one:
>> exceptions. A study of all the alternative ways to reporting errors was
>> requested so we can take a decision on which ones could be used once the
>> advantages and liabilities of each approach are detailed. I'm not a paper
>> writer and writing such a paper needs to be done carefully and it would
>> takes time. If there are any volunteers to write it, please do it, it will
>> be a pleasure to help. Of course, I will be very happy is this paper
>> unblocks the expected proposal.
>>
>
> The string_view to int paper could be a good candidate for such a study.
>
> On Wednesday, May 20, 2015 at 2:29:47 PM UTC-4, Thiago Macieira wrote:
>>
>> On Wednesday 20 May 2015 11:09:20 Nicol Bolas wrote:
>> > But one thing I'm adamantly against is being forced to use error codes.
>> > They should be *optional*, not mandatory. In C++, exceptions are the
>> > standard way of signaling errors; I shouldn't have to deal with error
>> codes
>> > unless I choose to.
>>
>> True, and on the other hand I'm hoping that the committee realises that
>> there's a world without exceptions. There are many environments where
>> exceptions cannot be used and it's irrelevant whether those reasons are
>> good
>> or bad. Making APIs that work for those environments increases their
>> use-base.
>>
>
> I agree with Thiago.
>
> Unfortunately, exceptions cannot be the standard C++ way.
>

But they are the standard way. That's how the standard signals failure.
Indeed, C++ class construction *cannot work* without exceptions (or at
least, cannot fail to work. Not in anything remotely like a sane manner).
And pretty much everything in the standard library that wasn't directly
inherited from C uses exceptions.

It is the standard way. The question is whether we should also, in some
cases, have an alternative. And what that alternative should be.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1122_369592545.1432148523711
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Ma=
tthew Fioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">On Wednesday, M=
ay 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba wrote:<br>Yes it=
s me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I'm not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br></blockquote><div><br>The string_view to int pape=
r could be a good candidate for such a study.<br></div><br>On Wednesday, Ma=
y 20, 2015 at 2:29:47 PM UTC-4, Thiago Macieira wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex">On Wednesday 20 May 2015 11:09:20 Nicol Bolas wrote:
<br>&gt; But one thing I'm adamantly against is being forced to use error c=
odes.=20
<br>&gt; They should be *optional*, not mandatory. In C++, exceptions are t=
he=20
<br>&gt; standard way of signaling errors; I shouldn't have to deal with er=
ror codes=20
<br>&gt; unless I choose to.
<br>
<br>True, and on the other hand I'm hoping that the committee realises that=
=20
<br>there's a world without exceptions. There are many environments where=
=20
<br>exceptions cannot be used and it's irrelevant whether those reasons are=
 good=20
<br>or bad. Making APIs that work for those environments increases their us=
e-base.
<br></blockquote><div><br>I agree with Thiago.<br><br>Unfortunately, except=
ions cannot be the standard C++ way.</div></div></blockquote><div><br>But t=
hey are the standard way. That's how the standard signals failure. Indeed, =
C++ class construction <i>cannot work</i> without exceptions (or at least, =
cannot fail to work. Not in anything remotely like a sane manner). And pret=
ty much everything in the standard library that wasn't directly inherited f=
rom C uses exceptions.<br><br>It is the standard way. The question is wheth=
er we should also, in some cases, have an alternative. And what that altern=
ative should be.</div></div>

<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 />

------=_Part_1122_369592545.1432148523711--
------=_Part_1121_294283598.1432148523711--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 May 2015 12:21:23 -0700 (PDT)
Raw View
------=_Part_4369_1188757223.1432149683180
Content-Type: multipart/alternative;
 boundary="----=_Part_4370_330504655.1432149683180"

------=_Part_4370_330504655.1432149683180
Content-Type: text/plain; charset=UTF-8

On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:
>
> A good example of this is the cppformat library which is a modern printf
> replacement. This library throws exceptions if you don't match the number
> of parameters with the number of "{}" in your format string. The first
> thing I did was disable exceptions here. Imagine your entire system
> crashing just because someone forgot to format a log message correctly?
>

This is actually a perfect example of why you *shouldn't* turn off
exceptions like this. As well as illustrating the limitations of
`expected`. Why?

Because by turning off exceptions, you allow bugs to exist. If the user
passes the wrong parameters to the logging function, that is a bug. And
because you turned off exceptions, you won't know its there unless you
check your log. And even then, you might simply miss it (it's not clear
what happens in the event of such an error). Not to mention, there's the
question of how `cppformat` behaves when you turn off exception handling;
does it do something sane, like not emit a string, or does it start walking
and/or trashing random memory?

`expected` can't fix that, since there's no return value from logging. So
not only is there an error, but you have no means of communicating that
error. Oh, you could return an `expected<void, E>`, but who checks a return
value from a function that doesn't have one?

It should also be noted that the exception behavior is much better than,
say, printf's behavior when given the wrong set of parameters. That
behavior being *undefined*, which will almost certainly involve walking
and/or trashing random memory. A guaranteed exception/crash is better than
a "maybe crash, maybe overwrite the balance on someone's account."

I've been in plenty of environments where a crash at the wrong time in
> production could result in huge unrecoverable losses.
>

Arbitrarily trashing memory at the wrong time is just as bad, if not worse.

Exceptions aren't bad; generating errors is what is bad. Exceptions are
just telling you that you generated one and forcing you to actually deal
with it, rather than pretending it didn't happen.

It should also be noted that, if you enter a scenario where crashing via
exception is not an option, you can always bracket it in a catch(...)
clause. In that case, it's basically about cleanup for something
fantastically bad that happened; just restore things to a sane state and
proceed.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_4370_330504655.1432149683180
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fi=
oravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div>A good example of this is the cppformat library which is a modern pr=
intf replacement. This library throws exceptions if you don't match the num=
ber of parameters with the number of "{}" in your format string. The first =
thing I did was disable exceptions here. Imagine your entire system crashin=
g just because someone forgot to format a log message correctly?</div></div=
></blockquote><div><br>This is actually a perfect example of why you <i>sho=
uldn't</i> turn off exceptions like this. As well as illustrating the limit=
ations of `expected`. Why?<br><br>Because by turning off exceptions, you al=
low bugs to exist. If the user passes the wrong parameters to the logging f=
unction, that is a bug. And because you turned off exceptions, you won't kn=
ow its there unless you check your log. And even then, you might simply mis=
s it (it's not clear what happens in the event of such an error). Not to me=
ntion, there's the question of how `cppformat` behaves when you turn off ex=
ception handling; does it do something sane, like not emit a string, or doe=
s it start walking and/or trashing random memory?<br><br>`expected` can't f=
ix that, since there's no return value from logging. So not only is there a=
n error, but you have no means of communicating that error. Oh, you could r=
eturn an `expected&lt;void, E&gt;`, but who checks a return value from a fu=
nction that doesn't have one?<br><br>It should also be noted that the excep=
tion behavior is much better than, say, printf's behavior when given the wr=
ong set of parameters. That behavior being <i>undefined</i>, which will alm=
ost certainly involve walking and/or trashing random memory. A guaranteed e=
xception/crash is better than a "maybe crash, maybe overwrite the balance o=
n someone's account."<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>I've been in plenty of environments where a cra=
sh at the wrong time in production could result in huge unrecoverable losse=
s.<br></div></div></blockquote><div><br>Arbitrarily trashing memory at the =
wrong time is just as bad, if not worse.<br><br>Exceptions aren't bad; gene=
rating errors is what is bad. Exceptions are just telling you that you gene=
rated one and forcing you to actually deal with it, rather than pretending =
it didn't happen.<br><br>It should also be noted that, if you enter a scena=
rio where crashing via exception is not an option, you can always bracket i=
t in a catch(...) clause. In that case, it's basically about cleanup for so=
mething fantastically bad that happened; just restore things to a sane stat=
e and proceed.<br></div></div>

<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 />

------=_Part_4370_330504655.1432149683180--
------=_Part_4369_1188757223.1432149683180--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 20 May 2015 12:55:53 -0700 (PDT)
Raw View
------=_Part_958_1764965377.1432151753386
Content-Type: multipart/alternative;
 boundary="----=_Part_959_581475228.1432151753386"

------=_Part_959_581475228.1432151753386
Content-Type: text/plain; charset=UTF-8



On Wednesday, May 20, 2015 at 3:21:23 PM UTC-4, Nicol Bolas wrote:
>
> On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:
>>
>> A good example of this is the cppformat library which is a modern printf
>> replacement. This library throws exceptions if you don't match the number
>> of parameters with the number of "{}" in your format string. The first
>> thing I did was disable exceptions here. Imagine your entire system
>> crashing just because someone forgot to format a log message correctly?
>>
>
> This is actually a perfect example of why you *shouldn't* turn off
> exceptions like this. As well as illustrating the limitations of
> `expected`. Why?
>
> Because by turning off exceptions, you allow bugs to exist.
>

I can live with an incorrect line in a log file (and an additional message
in the log file to tell me there was an error with cppformat that I need to
fix). I cannot live with a crash in production for something benign which
could result in more losses for my organization than my yearly income.


> If the user passes the wrong parameters to the logging function, that is a
> bug. And because you turned off exceptions, you won't know its there unless
> you check your log.
>

You can always reenable exceptions or assert() in debug builds to catch
these errors. In general I am a devout follower of the "fail early and
loudly" approach but this isn't always appropriate for all production
environmets.


> And even then, you might simply miss it (it's not clear what happens in
> the event of such an error). Not to mention, there's the question of how
> `cppformat` behaves when you turn off exception handling; does it do
> something sane, like not emit a string, or does it start walking and/or
> trashing random memory?
>

This particular library has support for enabling/disabling exceptions via a
macro. Of course blindly disabling exceptions when you aren't sure if the
library will work correctly without them is not a real solution.


>
> `expected` can't fix that, since there's no return value from logging. So
> not only is there an error, but you have no means of communicating that
> error. Oh, you could return an `expected<void, E>`, but who checks a return
> value from a function that doesn't have one?
>

Well of course in this example the best scenario is to have the compiler
check the format string. expected doesn't help with my example but its an
example to show when exceptions can do more harm then good, not a use case
for expected.


>
> It should also be noted that the exception behavior is much better than,
> say, printf's behavior when given the wrong set of parameters. That
> behavior being *undefined*, which will almost certainly involve walking
> and/or trashing random memory. A guaranteed exception/crash is better than
> a "maybe crash, maybe overwrite the balance on someone's account."
>

I agree, an assert() or throw or crash is always better than UB. The
situation however is not always this extreme.


>
> I've been in plenty of environments where a crash at the wrong time in
>> production could result in huge unrecoverable losses.
>>
>
> Arbitrarily trashing memory at the wrong time is just as bad, if not worse.
>

Its not always a black and white choice of throw an exception or trigger
UB. Like the example of my logger, its can be a choice of throw an
exception and crash or output some garbage to the log file.


>
> Exceptions aren't bad; generating errors is what is bad. Exceptions are
> just telling you that you generated one and forcing you to actually deal
> with it, rather than pretending it didn't happen.
>

Not all errors are the same.

Some are critical, in which an assert()/throw/abort() is appropriate. Some
are slightly annoying but mostly benign (logging). Some will reduce the
performance of your objective (say 1 module out of 10 fails, so now we only
run at 90% capacity) but are not critical enough to bring the whole system
down and run at 0% capacity.


>
> It should also be noted that, if you enter a scenario where crashing via
> exception is not an option, you can always bracket it in a catch(...)
> clause. In that case, it's basically about cleanup for something
> fantastically bad that happened; just restore things to a sane state and
> proceed.
>

This approach works sometimes when you can firewall exceptions around a
small well defined section of code. For example if you have a routine which
parses a file and returns an object, you can use an IO library which throws
exceptions and wrap the usage in a try/catch. You can easily log the IO
error in the catch() clause and then return your "error" status outside to
the exception unsafe world.

In general however, this approach sounds nice in theory but not so easy in
practice. Your "restore things to a sane state and proceed" stage requires
a lot of care. In order to recover from an error you need to know which
error occurred, what triggered it, and how to rollback *the entire
application* to a valid state.. Unless you're carefully using RAII to
rollback every action, you need to be extremely careful. My IO example this
approach was doable because it has simple "All or nothing" semantics.

I can't hope to recover anything if I just catch a random exception from
god knows where. Blindly trying to resume without knowing what actually
happened or what the side effects are sounds like a recipe for intractable
bugs. You cannot possibly hope to unit test or make any statements about
correctness for all of those code paths.

In the same way that using new / delete (instead of unique_ptr) means you
can never be quite sure your program doesn't leak, using exceptions means
you can never be quite sure it won't randomly crash.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_959_581475228.1432151753386
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, May 20, 2015 at 3:21:23 PM UTC-4, Ni=
col Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>A good examp=
le of this is the cppformat library which is a modern printf replacement. T=
his library throws exceptions if you don't match the number of parameters w=
ith the number of "{}" in your format string. The first thing I did was dis=
able exceptions here. Imagine your entire system crashing just because some=
one forgot to format a log message correctly?</div></div></blockquote><div>=
<br>This is actually a perfect example of why you <i>shouldn't</i> turn off=
 exceptions like this. As well as illustrating the limitations of `expected=
`. Why?<br><br>Because by turning off exceptions, you allow bugs to exist. =
</div></div></blockquote><div><br>I can live with an incorrect line in a lo=
g file (and an additional message in the log file to tell me there was an e=
rror with cppformat that I need to fix). I cannot live with a crash in prod=
uction for something benign which could result in more losses for my organi=
zation than my yearly income.<br>&nbsp;</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div>If the user passes the wrong parameter=
s to the logging function, that is a bug. And because you turned off except=
ions, you won't know its there unless you check your log.</div></div></bloc=
kquote><div><br>You can always reenable exceptions or assert() in debug bui=
lds to catch these errors. In general I am a devout follower of the "fail e=
arly and loudly" approach but this isn't always appropriate for all product=
ion environmets.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div dir=3D"ltr"><div> And even then, you might simply miss it (it's not =
clear what happens in the event of such an error). Not to mention, there's =
the question of how `cppformat` behaves when you turn off exception handlin=
g; does it do something sane, like not emit a string, or does it start walk=
ing and/or trashing random memory?<br></div></div></blockquote><div><br>Thi=
s particular library has support for enabling/disabling exceptions via a ma=
cro. Of course blindly disabling exceptions when you aren't sure if the lib=
rary will work correctly without them is not a real solution.<br>&nbsp;</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>`e=
xpected` can't fix that, since there's no return value from logging. So not=
 only is there an error, but you have no means of communicating that error.=
 Oh, you could return an `expected&lt;void, E&gt;`, but who checks a return=
 value from a function that doesn't have one?<br></div></div></blockquote><=
div><br>Well of course in this example the best scenario is to have the com=
piler check the format string. expected doesn't help with my example but it=
s an example to show when exceptions can do more harm then good, not a use =
case for expected.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><br>It should also be noted that the exception =
behavior is much better than, say, printf's behavior when given the wrong s=
et of parameters. That behavior being <i>undefined</i>, which will almost c=
ertainly involve walking and/or trashing random memory. A guaranteed except=
ion/crash is better than a "maybe crash, maybe overwrite the balance on som=
eone's account."<br></div></div></blockquote><div><br>I agree, an assert() =
or throw or crash is always better than UB. The situation however is not al=
ways this extreme.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>I've been in plenty of environments where a crash =
at the wrong time in production could result in huge unrecoverable losses.<=
br></div></div></blockquote><div><br>Arbitrarily trashing memory at the wro=
ng time is just as bad, if not worse.<br></div></div></blockquote><div><br>=
Its not always a black and white choice of throw an exception or trigger UB=
.. Like the example of my logger, its can be a choice of throw an exception =
and crash or output some garbage to the log file.<br>&nbsp;</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>Exceptions are=
n't bad; generating errors is what is bad. Exceptions are just telling you =
that you generated one and forcing you to actually deal with it, rather tha=
n pretending it didn't happen.<br></div></div></blockquote><div><br>Not all=
 errors are the same. <br><br>Some are critical, in which an assert()/throw=
/abort() is appropriate. Some are slightly annoying but mostly benign (logg=
ing). Some will reduce the performance of your objective (say 1 module out =
of 10 fails, so now we only run at 90% capacity) but are not critical enoug=
h to bring the whole system down and run at 0% capacity.<br>&nbsp;</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>It shou=
ld also be noted that, if you enter a scenario where crashing via exception=
 is not an option, you can always bracket it in a catch(...) clause. In tha=
t case, it's basically about cleanup for something fantastically bad that h=
appened; just restore things to a sane state and proceed.<br></div></div></=
blockquote><div><br>This approach works sometimes when you can firewall exc=
eptions around a small well defined section of code. For example if you hav=
e a routine which parses a file and returns an object, you can use an IO li=
brary which throws exceptions and wrap the usage in a try/catch. You can ea=
sily log the IO error in the catch() clause and then return your "error" st=
atus outside to the exception unsafe world.<br><br>In general however, this=
 approach sounds nice in theory but not so easy in practice. Your "restore =
things to a sane state and proceed" stage requires a lot of care. In order =
to recover from an error you need to know which error occurred, what trigge=
red it, and how to rollback <b>the entire application</b> to a valid state.=
.. Unless you're carefully using RAII to rollback every action, you need to =
be extremely careful. My IO example this approach was doable because it has=
 simple "All or nothing" semantics.<br><br>I can't hope to recover anything=
 if I just catch a random exception from god knows where. Blindly trying to=
 resume without knowing what actually happened or what the side effects are=
 sounds like a recipe for intractable bugs. You cannot possibly hope to uni=
t test or make any statements about correctness for all of those code paths=
..<br><br>In the same way that using new / delete (instead of unique_ptr) me=
ans you can never be quite sure your program doesn't leak, using exceptions=
 means you can never be quite sure it won't randomly crash.<br><br><br></di=
v></div>

<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 />

------=_Part_959_581475228.1432151753386--
------=_Part_958_1764965377.1432151753386--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 20 May 2015 15:34:16 -0500
Raw View
--001a11c23fb631534f0516895ccc
Content-Type: text/plain; charset=UTF-8

On 20 May 2015 at 14:55, Matthew Fioravante <fmatthew5876@gmail.com> wrote:

>
> I can live with an incorrect line in a log file (and an additional message
> in the log file to tell me there was an error with cppformat that I need to
> fix).
>

I'm not sure why you'd ever get that second line.  Either it is a
precondition for calling your function or it isn't.


> I cannot live with a crash in production for something benign which could
> result in more losses for my organization than my yearly income.
>

How do you know the programming bug is benign and not symptomatic of
something far worse?

You are pretending the code knows the root cause of the programming bug it
was never supposed to have and can magically recover from it.  Seems very
risky to me...
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c23fb631534f0516895ccc
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 2=
0 May 2015 at 14:55, Matthew Fioravante <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.com</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);borde=
r-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><br>=
</span><div>I can live with an incorrect line in a log file (and an additio=
nal message in the log file to tell me there was an error with cppformat th=
at I need to fix).</div></div></blockquote><div><br></div><div>I&#39;m not =
sure why you&#39;d ever get that second line.=C2=A0 Either it is a precondi=
tion for calling your function or it isn&#39;t.</div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div> I cannot live with a crash in production=
 for something benign which could result in more losses for my organization=
 than my yearly income.<br></div></div></blockquote><div><br></div><div><sp=
an style=3D"font-size:12.8000001907349px">How do you know the programming b=
ug is benign and not=C2=A0symptomatic=C2=A0of something far worse?</span></=
div><div><span style=3D"font-size:12.8000001907349px"><br></span></div><div=
><span style=3D"font-size:12.8000001907349px">You are pretending the code k=
nows the root cause of the programming bug it was never supposed to have an=
d can magically recover from it.=C2=A0 Seems very risky to me...</span></di=
v></div>-- <br><div class=3D"gmail_signature">=C2=A0Nevin &quot;:-)&quot; L=
iber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_=
blank">nevin@eviloverlord.com</a>&gt;=C2=A0 (847) 691-1404</div>
</div></div>

<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 />

--001a11c23fb631534f0516895ccc--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 20 May 2015 13:52:37 -0700
Raw View
--001a1130d45e777a1d0516899b01
Content-Type: text/plain; charset=UTF-8

On Wed, May 20, 2015 at 12:21 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:
>>
>> A good example of this is the cppformat library which is a modern printf
>> replacement. This library throws exceptions if you don't match the number
>> of parameters with the number of "{}" in your format string. The first
>> thing I did was disable exceptions here. Imagine your entire system
>> crashing just because someone forgot to format a log message correctly?
>>
>
> This is actually a perfect example of why you *shouldn't* turn off
> exceptions like this. As well as illustrating the limitations of
> `expected`. Why?
>
> Because by turning off exceptions, you allow bugs to exist. If the user
> passes the wrong parameters to the logging function, that is a bug. And
> because you turned off exceptions, you won't know its there unless you
> check your log. And even then, you might simply miss it (it's not clear
> what happens in the event of such an error). Not to mention, there's the
> question of how `cppformat` behaves when you turn off exception handling;
> does it do something sane, like not emit a string, or does it start walking
> and/or trashing random memory?
>
> `expected` can't fix that, since there's no return value from logging. So
> not only is there an error, but you have no means of communicating that
> error. Oh, you could return an `expected<void, E>`, but who checks a return
> value from a function that doesn't have one?
>
> It should also be noted that the exception behavior is much better than,
> say, printf's behavior when given the wrong set of parameters. That
> behavior being *undefined*, which will almost certainly involve walking
> and/or trashing random memory. A guaranteed exception/crash is better than
> a "maybe crash, maybe overwrite the balance on someone's account."
>

At risk of derailing this discussion, I want to take a step back and give
my perspective about exceptions in current C++, "expected", and what I
personally consider "ideal" for exceptional cases (failures to meet a
post-condition).

"expected", or discriminated unions in general, provide many benefits, and
some drawbacks, over exceptions:

==========

Discriminated union (treated as "expected" with N unexpected cases):
Pros:
Not dependent on some global RTTI
Control flow is very clear
Handling of errors is generally as efficient as dealing with results
Users know exactly the kinds of errors that can come up and if they are all
handled
Can effectively turn the closed-set into an open set by having an
"expected" with a runtime polymorphic unexpected type
Cons:
Propagation is not automatic
Deals with a closed-set of types (also a pro, this is a trade-off)
You pay for the exceptional case by way of the return value and branching
even though it is an "uncommon" case
Errors can be silently missed if the return value is not checked (common if
return is void or there are other side-effects)
Changing the set of error kinds can change the function type
Dealing with the result of a function that can fail vs one that cannot is
considerably different
Not directly applicable for constructors (generally implies "make"
facilities that yield expected and is considerably annoying for copy
operations that can fail)
(IMO) Difficult to work with in generic code that needs to potentially
propagate errors from user-defined code that may or may not throw

C++ Exceptions:
Pros:
Open set of types (this is a trade-off)
Function type does not change as different kinds of failures are
added/removed
Dealing with the expected return type is as easy as the case when the
function cannot fail
Changing a function that is noexcept to one that that is not (or vice
versa) does not affect use of the result
They play well with constructors
(IMO) Easier to work with in generic code that calls into user-defined
functions that may or may not throw and an exception would need to propagate
Cons:
Open set of exception types means it's difficult to know if all exception
kinds are dealt with
Control flow can be extremely subtle and complex when taking into account
exceptions, especially in generic code that interacts with user-defined
functions that may or may not throw
Open set of types and the way catching works means dependence on more
sophisticated RTTI

==========

Feel free to correct anything that is wrong in the above assessment or to
add to it. I am not an expert in this domain and these are just my personal
thoughts.

First off, the most obvious thing to get out of this, in my opinion, is
that "we already have exceptions" is not a sufficient answer for why we
should avoid standardizing something like "expected". There are trade-offs
and the assumption that using C++ exceptions is always the proper solution
is as flawed as saying that everyone should always use specifically any one
of the standard containers. Different situations have different needs. I
really do feel that something like "expected" is worthwhile, even though I
find that the proposal has some separate flaws.

Not that the following has any chance of changing the language, but my
personal thoughts have been that C++ exceptions are good, but would ideally
be much more like a discriminated union in terms of implementation. By that
I mean they still would not affect the return type of the function, as is
already the case with current exceptions though not with "expected", but
they would deal with a closed set of types rather than an open set. You
would be able to query at compile time the set of possible exceptions and
append to that set when making higher level functions (important for
generic code -- this is also analogous to using noexcept to determine if an
expression can throw or not). You'd always be able to effectively make an
open set of exception types by using some kind of a polymorphic type (I.E.
a type-erased object with a large small-object optimization), though you
would lose some of the functionality of C++ exceptions as they are in the
language. Exception propagation would continue to work as-is, as would
accessing of the normal result of a function. Constructors would also work
as easily as they do right now.

This would basically just be C++ exceptions, only implemented on top of a
discriminated union instead of an open set of types.

Anyway, some of this is sort of a derail but those are my thoughts. In
practice I find that using something like "expected" is very useful and has
important practical implications, but I'm also a fan of many of the
properties of exceptions.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a1130d45e777a1d0516899b01
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, May 20, 2015 at 12:21 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</=
span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-le=
ft-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On Wedne=
sday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:</span><sp=
an class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>A good example of this=
 is the cppformat library which is a modern printf replacement. This librar=
y throws exceptions if you don&#39;t match the number of parameters with th=
e number of &quot;{}&quot; in your format string. The first thing I did was=
 disable exceptions here. Imagine your entire system crashing just because =
someone forgot to format a log message correctly?</div></div></blockquote><=
/span><div><br>This is actually a perfect example of why you <i>shouldn&#39=
;t</i> turn off exceptions like this. As well as illustrating the limitatio=
ns of `expected`. Why?<br><br>Because by turning off exceptions, you allow =
bugs to exist. If the user passes the wrong parameters to the logging funct=
ion, that is a bug. And because you turned off exceptions, you won&#39;t kn=
ow its there unless you check your log. And even then, you might simply mis=
s it (it&#39;s not clear what happens in the event of such an error). Not t=
o mention, there&#39;s the question of how `cppformat` behaves when you tur=
n off exception handling; does it do something sane, like not emit a string=
, or does it start walking and/or trashing random memory?<br><br>`expected`=
 can&#39;t fix that, since there&#39;s no return value from logging. So not=
 only is there an error, but you have no means of communicating that error.=
 Oh, you could return an `expected&lt;void, E&gt;`, but who checks a return=
 value from a function that doesn&#39;t have one?<br><br>It should also be =
noted that the exception behavior is much better than, say, printf&#39;s be=
havior when given the wrong set of parameters. That behavior being <i>undef=
ined</i>, which will almost certainly involve walking and/or trashing rando=
m memory. A guaranteed exception/crash is better than a &quot;maybe crash, =
maybe overwrite the balance on someone&#39;s account.&quot;</div></div></bl=
ockquote><div><br></div><div>At risk of derailing this discussion, I want t=
o take a step back and give my perspective about exceptions in current C++,=
 &quot;expected&quot;, and what I personally consider &quot;ideal&quot; for=
 exceptional cases (failures to meet a post-condition).</div><div><br></div=
><div>&quot;expected&quot;, or discriminated unions in general, provide man=
y benefits, and some drawbacks, over exceptions:</div><div><br></div><div>=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D</div><div><br></div><div>Discriminated union=
 (treated as &quot;expected&quot; with N unexpected cases):</div><div>Pros:=
</div><div>Not dependent on some global RTTI</div><div>Control flow is very=
 clear</div><div>Handling of errors is generally as efficient as dealing wi=
th results</div><div>Users know exactly the kinds of errors that can come u=
p and if they are all handled</div><div>Can effectively turn the closed-set=
 into an open set by having an &quot;expected&quot; with a runtime polymorp=
hic unexpected type</div><div>Cons:</div><div>Propagation is not automatic<=
/div><div>Deals with a closed-set of types (also a pro, this is a trade-off=
)</div>You pay for the exceptional case by way of the return value and bran=
ching even though it is an &quot;uncommon&quot; case<div>Errors can be sile=
ntly missed if the return value is not checked (common if return is void or=
 there are other side-effects)</div><div>Changing the set of error kinds ca=
n change the function type</div><div>Dealing with the result of a function =
that can fail vs one that cannot is considerably different</div><div>Not di=
rectly applicable for constructors (generally implies &quot;make&quot; faci=
lities that yield expected and is considerably annoying for copy operations=
 that can fail)</div><div>(IMO) Difficult to work with in generic code that=
 needs to potentially propagate errors from user-defined code that may or m=
ay not throw</div><div><br></div><div>C++ Exceptions:</div><div>Pros:</div>=
<div>Open set of types (this is a trade-off)</div><div>Function type does n=
ot change as different kinds of failures are added/removed</div><div>Dealin=
g with the expected return type is as easy as the case when the function ca=
nnot fail</div><div>Changing a function that is noexcept to one that that i=
s not (or vice versa) does not affect use of the result</div><div>They play=
 well with constructors</div><div>(IMO) Easier to work with in generic code=
 that calls into user-defined functions that may or may not throw and an ex=
ception would need to propagate</div><div>Cons:</div><div>Open set of excep=
tion types means it&#39;s difficult to know if all exception kinds are deal=
t with</div>Control flow can be extremely subtle and complex when taking in=
to account exceptions, especially in generic code that interacts with user-=
defined functions that may or may not throw<div>Open set of types and the w=
ay catching works means dependence on more sophisticated RTTI</div><div><br=
></div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D</div><div><br></div><div>Feel fr=
ee to correct anything that is wrong in the above assessment or to add to i=
t. I am not an expert in this domain and these are just my personal thought=
s.</div><div><br></div><div>First off, the most obvious thing to get out of=
 this, in my opinion, is that &quot;we already have exceptions&quot; is not=
 a sufficient answer for why we should avoid standardizing something like &=
quot;expected&quot;. There are trade-offs and the assumption that using C++=
 exceptions is always the proper solution is as flawed as saying that every=
one should always use specifically any one of the standard containers. Diff=
erent situations have different needs. I really do feel that something like=
 &quot;expected&quot; is worthwhile, even though I find that the proposal h=
as some separate flaws.</div><div><br></div><div>Not that the following has=
 any chance of changing the language, but my personal thoughts have been th=
at C++ exceptions are good, but would ideally be much more like a discrimin=
ated union in terms of implementation. By that I mean they still would not =
affect the return type of the function, as is already the case with current=
 exceptions though not with &quot;expected&quot;, but they would deal with =
a closed set of types rather than an open set. You would be able to query a=
t compile time the set of possible exceptions and append to that set when m=
aking higher level functions (important for generic code -- this is also an=
alogous to using noexcept to determine if an expression can throw or not). =
You&#39;d always be able to effectively make an open set of exception types=
 by using some kind of a polymorphic type (I.E. a type-erased object with a=
 large small-object optimization), though you would lose some of the functi=
onality of C++ exceptions as they are in the language. Exception propagatio=
n would continue to work as-is, as would accessing of the normal result of =
a function. Constructors would also work as easily as they do right now.</d=
iv><div><br></div><div>This would basically just be C++ exceptions, only im=
plemented on top of a discriminated union instead of an open set of types.<=
/div><div><br></div><div>Anyway, some of this is sort of a derail but those=
 are my thoughts. In practice I find that using something like &quot;expect=
ed&quot; is very useful and has important practical implications, but I&#39=
;m also a fan of many of the properties of exceptions.</div></div></div></d=
iv>

<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 />

--001a1130d45e777a1d0516899b01--

.


Author: Jeremy Maitin-Shepard <jeremy@jeremyms.com>
Date: Wed, 20 May 2015 14:33:55 -0700 (PDT)
Raw View
------=_Part_5003_688511534.1432157635173
Content-Type: multipart/alternative;
 boundary="----=_Part_5004_1171461902.1432157635173"

------=_Part_5004_1171461902.1432157635173
Content-Type: text/plain; charset=UTF-8

The version of excepted that holds an exception_ptr is also very useful
even when exceptions are used: it encapsulates the "result or exception"
pattern that underlies std::future and is very useful in cases where the
heavy-weight notification and waiting functionality (as well as thread
safety) of std::future is not required.  It would probably make sense to
make std::future explicitly interoperable with excepted.

On Wednesday, May 20, 2015 at 1:52:39 PM UTC-7, Matt Calabrese wrote:
>
> On Wed, May 20, 2015 at 12:21 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Wednesday, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:
>>>
>>> A good example of this is the cppformat library which is a modern printf
>>> replacement. This library throws exceptions if you don't match the number
>>> of parameters with the number of "{}" in your format string. The first
>>> thing I did was disable exceptions here. Imagine your entire system
>>> crashing just because someone forgot to format a log message correctly?
>>>
>>
>> This is actually a perfect example of why you *shouldn't* turn off
>> exceptions like this. As well as illustrating the limitations of
>> `expected`. Why?
>>
>> Because by turning off exceptions, you allow bugs to exist. If the user
>> passes the wrong parameters to the logging function, that is a bug. And
>> because you turned off exceptions, you won't know its there unless you
>> check your log. And even then, you might simply miss it (it's not clear
>> what happens in the event of such an error). Not to mention, there's the
>> question of how `cppformat` behaves when you turn off exception handling;
>> does it do something sane, like not emit a string, or does it start walking
>> and/or trashing random memory?
>>
>> `expected` can't fix that, since there's no return value from logging. So
>> not only is there an error, but you have no means of communicating that
>> error. Oh, you could return an `expected<void, E>`, but who checks a return
>> value from a function that doesn't have one?
>>
>> It should also be noted that the exception behavior is much better than,
>> say, printf's behavior when given the wrong set of parameters. That
>> behavior being *undefined*, which will almost certainly involve walking
>> and/or trashing random memory. A guaranteed exception/crash is better than
>> a "maybe crash, maybe overwrite the balance on someone's account."
>>
>
> At risk of derailing this discussion, I want to take a step back and give
> my perspective about exceptions in current C++, "expected", and what I
> personally consider "ideal" for exceptional cases (failures to meet a
> post-condition).
>
> "expected", or discriminated unions in general, provide many benefits, and
> some drawbacks, over exceptions:
>
> ==========
>
> Discriminated union (treated as "expected" with N unexpected cases):
> Pros:
> Not dependent on some global RTTI
> Control flow is very clear
> Handling of errors is generally as efficient as dealing with results
> Users know exactly the kinds of errors that can come up and if they are
> all handled
> Can effectively turn the closed-set into an open set by having an
> "expected" with a runtime polymorphic unexpected type
> Cons:
> Propagation is not automatic
> Deals with a closed-set of types (also a pro, this is a trade-off)
> You pay for the exceptional case by way of the return value and branching
> even though it is an "uncommon" case
> Errors can be silently missed if the return value is not checked (common
> if return is void or there are other side-effects)
> Changing the set of error kinds can change the function type
> Dealing with the result of a function that can fail vs one that cannot is
> considerably different
> Not directly applicable for constructors (generally implies "make"
> facilities that yield expected and is considerably annoying for copy
> operations that can fail)
> (IMO) Difficult to work with in generic code that needs to potentially
> propagate errors from user-defined code that may or may not throw
>
> C++ Exceptions:
> Pros:
> Open set of types (this is a trade-off)
> Function type does not change as different kinds of failures are
> added/removed
> Dealing with the expected return type is as easy as the case when the
> function cannot fail
> Changing a function that is noexcept to one that that is not (or vice
> versa) does not affect use of the result
> They play well with constructors
> (IMO) Easier to work with in generic code that calls into user-defined
> functions that may or may not throw and an exception would need to propagate
> Cons:
> Open set of exception types means it's difficult to know if all exception
> kinds are dealt with
> Control flow can be extremely subtle and complex when taking into account
> exceptions, especially in generic code that interacts with user-defined
> functions that may or may not throw
> Open set of types and the way catching works means dependence on more
> sophisticated RTTI
>
> ==========
>
> Feel free to correct anything that is wrong in the above assessment or to
> add to it. I am not an expert in this domain and these are just my personal
> thoughts.
>
> First off, the most obvious thing to get out of this, in my opinion, is
> that "we already have exceptions" is not a sufficient answer for why we
> should avoid standardizing something like "expected". There are trade-offs
> and the assumption that using C++ exceptions is always the proper solution
> is as flawed as saying that everyone should always use specifically any one
> of the standard containers. Different situations have different needs. I
> really do feel that something like "expected" is worthwhile, even though I
> find that the proposal has some separate flaws.
>
> Not that the following has any chance of changing the language, but my
> personal thoughts have been that C++ exceptions are good, but would ideally
> be much more like a discriminated union in terms of implementation. By that
> I mean they still would not affect the return type of the function, as is
> already the case with current exceptions though not with "expected", but
> they would deal with a closed set of types rather than an open set. You
> would be able to query at compile time the set of possible exceptions and
> append to that set when making higher level functions (important for
> generic code -- this is also analogous to using noexcept to determine if an
> expression can throw or not). You'd always be able to effectively make an
> open set of exception types by using some kind of a polymorphic type (I.E.
> a type-erased object with a large small-object optimization), though you
> would lose some of the functionality of C++ exceptions as they are in the
> language. Exception propagation would continue to work as-is, as would
> accessing of the normal result of a function. Constructors would also work
> as easily as they do right now.
>
> This would basically just be C++ exceptions, only implemented on top of a
> discriminated union instead of an open set of types.
>
> Anyway, some of this is sort of a derail but those are my thoughts. In
> practice I find that using something like "expected" is very useful and has
> important practical implications, but I'm also a fan of many of the
> properties of exceptions.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5004_1171461902.1432157635173
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">The version of excepted that holds an exception_ptr is als=
o very useful even when exceptions are used: it encapsulates the "result or=
 exception" pattern that underlies std::future and is very useful in cases =
where the heavy-weight notification and waiting functionality (as well as t=
hread safety) of std::future is not required.&nbsp; It would probably make =
sense to make std::future explicitly interoperable with excepted.<br><br>On=
 Wednesday, May 20, 2015 at 1:52:39 PM UTC-7, Matt Calabrese wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gm=
ail_quote">On Wed, May 20, 2015 at 12:21 PM, Nicol Bolas <span dir=3D"ltr">=
&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"2Oxh=
2-IOvEsJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return =
true;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span>On Wednes=
day, May 20, 2015 at 2:49:59 PM UTC-4, Matthew Fioravante wrote:</span><spa=
n><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid=
;padding-left:1ex"><div dir=3D"ltr"><div>A good example of this is the cppf=
ormat library which is a modern printf replacement. This library throws exc=
eptions if you don't match the number of parameters with the number of "{}"=
 in your format string. The first thing I did was disable exceptions here. =
Imagine your entire system crashing just because someone forgot to format a=
 log message correctly?</div></div></blockquote></span><div><br>This is act=
ually a perfect example of why you <i>shouldn't</i> turn off exceptions lik=
e this. As well as illustrating the limitations of `expected`. Why?<br><br>=
Because by turning off exceptions, you allow bugs to exist. If the user pas=
ses the wrong parameters to the logging function, that is a bug. And becaus=
e you turned off exceptions, you won't know its there unless you check your=
 log. And even then, you might simply miss it (it's not clear what happens =
in the event of such an error). Not to mention, there's the question of how=
 `cppformat` behaves when you turn off exception handling; does it do somet=
hing sane, like not emit a string, or does it start walking and/or trashing=
 random memory?<br><br>`expected` can't fix that, since there's no return v=
alue from logging. So not only is there an error, but you have no means of =
communicating that error. Oh, you could return an `expected&lt;void, E&gt;`=
, but who checks a return value from a function that doesn't have one?<br><=
br>It should also be noted that the exception behavior is much better than,=
 say, printf's behavior when given the wrong set of parameters. That behavi=
or being <i>undefined</i>, which will almost certainly involve walking and/=
or trashing random memory. A guaranteed exception/crash is better than a "m=
aybe crash, maybe overwrite the balance on someone's account."</div></div><=
/blockquote><div><br></div><div>At risk of derailing this discussion, I wan=
t to take a step back and give my perspective about exceptions in current C=
++, "expected", and what I personally consider "ideal" for exceptional case=
s (failures to meet a post-condition).</div><div><br></div><div>"expected",=
 or discriminated unions in general, provide many benefits, and some drawba=
cks, over exceptions:</div><div><br></div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D</div><div><br></div><div>Discriminated union (treated as "expected" wit=
h N unexpected cases):</div><div>Pros:</div><div>Not dependent on some glob=
al RTTI</div><div>Control flow is very clear</div><div>Handling of errors i=
s generally as efficient as dealing with results</div><div>Users know exact=
ly the kinds of errors that can come up and if they are all handled</div><d=
iv>Can effectively turn the closed-set into an open set by having an "expec=
ted" with a runtime polymorphic unexpected type</div><div>Cons:</div><div>P=
ropagation is not automatic</div><div>Deals with a closed-set of types (als=
o a pro, this is a trade-off)</div>You pay for the exceptional case by way =
of the return value and branching even though it is an "uncommon" case<div>=
Errors can be silently missed if the return value is not checked (common if=
 return is void or there are other side-effects)</div><div>Changing the set=
 of error kinds can change the function type</div><div>Dealing with the res=
ult of a function that can fail vs one that cannot is considerably differen=
t</div><div>Not directly applicable for constructors (generally implies "ma=
ke" facilities that yield expected and is considerably annoying for copy op=
erations that can fail)</div><div>(IMO) Difficult to work with in generic c=
ode that needs to potentially propagate errors from user-defined code that =
may or may not throw</div><div><br></div><div>C++ Exceptions:</div><div>Pro=
s:</div><div>Open set of types (this is a trade-off)</div><div>Function typ=
e does not change as different kinds of failures are added/removed</div><di=
v>Dealing with the expected return type is as easy as the case when the fun=
ction cannot fail</div><div>Changing a function that is noexcept to one tha=
t that is not (or vice versa) does not affect use of the result</div><div>T=
hey play well with constructors</div><div>(IMO) Easier to work with in gene=
ric code that calls into user-defined functions that may or may not throw a=
nd an exception would need to propagate</div><div>Cons:</div><div>Open set =
of exception types means it's difficult to know if all exception kinds are =
dealt with</div>Control flow can be extremely subtle and complex when takin=
g into account exceptions, especially in generic code that interacts with u=
ser-defined functions that may or may not throw<div>Open set of types and t=
he way catching works means dependence on more sophisticated RTTI</div><div=
><br></div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D</div><div><br></div><div>Fee=
l free to correct anything that is wrong in the above assessment or to add =
to it. I am not an expert in this domain and these are just my personal tho=
ughts.</div><div><br></div><div>First off, the most obvious thing to get ou=
t of this, in my opinion, is that "we already have exceptions" is not a suf=
ficient answer for why we should avoid standardizing something like "expect=
ed". There are trade-offs and the assumption that using C++ exceptions is a=
lways the proper solution is as flawed as saying that everyone should alway=
s use specifically any one of the standard containers. Different situations=
 have different needs. I really do feel that something like "expected" is w=
orthwhile, even though I find that the proposal has some separate flaws.</d=
iv><div><br></div><div>Not that the following has any chance of changing th=
e language, but my personal thoughts have been that C++ exceptions are good=
, but would ideally be much more like a discriminated union in terms of imp=
lementation. By that I mean they still would not affect the return type of =
the function, as is already the case with current exceptions though not wit=
h "expected", but they would deal with a closed set of types rather than an=
 open set. You would be able to query at compile time the set of possible e=
xceptions and append to that set when making higher level functions (import=
ant for generic code -- this is also analogous to using noexcept to determi=
ne if an expression can throw or not). You'd always be able to effectively =
make an open set of exception types by using some kind of a polymorphic typ=
e (I.E. a type-erased object with a large small-object optimization), thoug=
h you would lose some of the functionality of C++ exceptions as they are in=
 the language. Exception propagation would continue to work as-is, as would=
 accessing of the normal result of a function. Constructors would also work=
 as easily as they do right now.</div><div><br></div><div>This would basica=
lly just be C++ exceptions, only implemented on top of a discriminated unio=
n instead of an open set of types.</div><div><br></div><div>Anyway, some of=
 this is sort of a derail but those are my thoughts. In practice I find tha=
t using something like "expected" is very useful and has important practica=
l implications, but I'm also a fan of many of the properties of exceptions.=
</div></div></div></div>
</blockquote></div>

<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 />

------=_Part_5004_1171461902.1432157635173--
------=_Part_5003_688511534.1432157635173--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 20 May 2015 17:23:01 -0500
Raw View
--089e011767f91dcce905168ae118
Content-Type: text/plain; charset=UTF-8

On 20 May 2015 at 13:09, Nicol Bolas <jmckesson@gmail.com> wrote:

> But one thing I'm adamantly against is being forced to use error codes.
> They should be *optional*, not mandatory. In C++, exceptions are the
> standard way of signaling errors; I shouldn't have to deal with error codes
> unless I choose to.
>

But that is not strictly true.

For instance, set::insert(value_type const&) returns a pair whose second
element tells you whether or not the insertion succeeded.

It's more about how unusual the failure is, whether it is likely to be
handled locally, etc.

For libraries like filesystem, there is no way to know whether the user
needs to handle it locally or not, so both are provided.  For instance, on
an embedded system, I might expect many of the files I open to just be
there, and it would be unusual if they weren't.  OTOH, if the user is
typing in a filename somewhere, I probably want to handle that locally.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e011767f91dcce905168ae118
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 2=
0 May 2015 at 13:09, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"mailto:jm=
ckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</span> wro=
te:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But one thing I=
&#39;m adamantly against is being forced to use error codes. They should be=
 <i>optional</i>, not mandatory. In C++, exceptions are the standard way of=
 signaling errors; I shouldn&#39;t have to deal with error codes unless I c=
hoose to.<br></div></div></blockquote><div><br></div><div>But that is not s=
trictly true.</div><div><br></div><div>For instance, set::insert(value_type=
 const&amp;) returns a pair whose second element tells you whether or not t=
he insertion succeeded.</div><div><br></div><div>It&#39;s more about how un=
usual the failure is, whether it is likely to be handled locally, etc.</div=
><div><br></div><div>For libraries like filesystem, there is no way to know=
 whether the user needs to handle it locally or not, so both are provided.=
=C2=A0 For instance, on an embedded system, I might expect many of the file=
s I open to just be there, and it would be unusual if they weren&#39;t.=C2=
=A0 OTOH, if the user is typing in a filename somewhere, I probably want to=
 handle that locally.</div></div>-- <br><div>=C2=A0Nevin &quot;:-)&quot; Li=
ber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_b=
lank">nevin@eviloverlord.com</a>&gt;=C2=A0 <a href=3D"tel:%28847%29%20691-1=
404" value=3D"+18476911404" target=3D"_blank">(847) 691-1404</a></div>
</div></div>

<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 />

--089e011767f91dcce905168ae118--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 May 2015 15:35:51 -0700 (PDT)
Raw View
------=_Part_662_1391708876.1432161351712
Content-Type: multipart/alternative;
 boundary="----=_Part_663_59195808.1432161351712"

------=_Part_663_59195808.1432161351712
Content-Type: text/plain; charset=UTF-8

On Wednesday, May 20, 2015 at 6:23:43 PM UTC-4, Nevin ":-)" Liber wrote:
>
> On 20 May 2015 at 13:09, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
>
>> But one thing I'm adamantly against is being forced to use error codes.
>> They should be *optional*, not mandatory. In C++, exceptions are the
>> standard way of signaling errors; I shouldn't have to deal with error codes
>> unless I choose to.
>>
>
> But that is not strictly true.
>
> For instance, set::insert(value_type const&) returns a pair whose second
> element tells you whether or not the insertion succeeded.
>

> It's more about how unusual the failure is, whether it is likely to be
> handled locally, etc.
>

I wouldn't say that.

set::insert returns the second value purely as a convenience to the user.
Attempting to insert the same element multiple times is not an error. The
purpose of a set is to hold a sequence of unique values. So if you try to
insert the same element multiple times... it's no different to the set than
if you inserted it once.

In short, it doesn't represent an *error*. You asked for the item to be put
in the list. And after the function call, the item is in the list; you can
fetch the item through `set`'s interface, just as if it weren't there
before.

The only reason the API even lets the user know the element was actually
inserted is because the user might choose to care, in some isolated cases.

Filesystem errors are legitimate *error* conditions. You asked the system
to do something, and it couldn't be done. That's not something you should
be able to ignore. Or at least, not without using some specific syntax
saying that you're ignoring it.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_663_59195808.1432161351712
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 20, 2015 at 6:23:43 PM UTC-4, Nevin ":-)=
" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div><div class=3D"gmail_quote">On 20 May 2015 at 13:09, Nicol Bolas <span=
 dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"Z6EKxMcg7-gJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return true;">jmck=
....@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>But one thing I'm adamantly against is being forced to use=
 error codes. They should be <i>optional</i>, not mandatory. In C++, except=
ions are the standard way of signaling errors; I shouldn't have to deal wit=
h error codes unless I choose to.<br></div></div></blockquote><div><br></di=
v><div>But that is not strictly true.</div><div><br></div><div>For instance=
, set::insert(value_type const&amp;) returns a pair whose second element te=
lls you whether or not the insertion succeeded.&nbsp;</div></div></div></di=
v></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div><div class=3D"gmail_quote"><div><br></div><div>It's more about how u=
nusual the failure is, whether it is likely to be handled locally, etc.</di=
v></div></div></div></blockquote><div><br>I wouldn't say that.<br><br>set::=
insert returns the second value purely as a convenience to the user. Attemp=
ting to insert the same element multiple times is not an error. The purpose=
 of a set is to hold a sequence of unique values. So if you try to insert t=
he same element multiple times... it's no different to the set than if you =
inserted it once.<br><br>In short, it doesn't represent an <i>error</i>. Yo=
u asked for the item to be put in the list. And after the function call, th=
e item is in the list; you can fetch the item through `set`'s interface, ju=
st as if it weren't there before.<br><br>The only reason the API even lets =
the user know the element was actually inserted is because the user might c=
hoose to care, in some isolated cases.<br><br>Filesystem errors are legitim=
ate <i>error</i> conditions. You asked the system to do something, and it c=
ouldn't be done. That's not something you should be able to ignore. Or at l=
east, not without using some specific syntax saying that you're ignoring it=
..</div></div>

<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 />

------=_Part_663_59195808.1432161351712--
------=_Part_662_1391708876.1432161351712--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 20 May 2015 15:42:12 -0700
Raw View
--90e6ba6e84604f43c305168b237c
Content-Type: text/plain; charset=UTF-8

On Wed, May 20, 2015 at 3:23 PM, Nevin Liber <nevin@eviloverlord.com> wrote:

> On 20 May 2015 at 13:09, Nicol Bolas <jmckesson@gmail.com> wrote:
>
>> But one thing I'm adamantly against is being forced to use error codes.
>> They should be *optional*, not mandatory. In C++, exceptions are the
>> standard way of signaling errors; I shouldn't have to deal with error codes
>> unless I choose to.
>>
>
> But that is not strictly true.
>
> For instance, set::insert(value_type const&) returns a pair whose second
> element tells you whether or not the insertion succeeded.
>
> It's more about how unusual the failure is, whether it is likely to be
> handled locally, etc.
>

I've never been a fan of classification based on how "usual" or "unusual"
something is because that often depends more on usage rather than being
known at the declaration, and even then what is "usual" vs "unusual" isn't
a clear line.

The way I think about things:
Exceptions are for when an implementation cannot meet a post-condition, but
where no invariants are violated. Exceptions do not logically change the
output space of the function.
Functions with "errors codes" or that use "expected" actually weaken
post-conditions by instead expanding the output space of the function such
that it now includes those failure states.

The choice of which is used mostly depends on practical concerns (i.e. what
ends up being more efficient for an application), and what users consider
easier to reason about or to deal with in higher-level code. Regarding what
is easier to reason about and deal with, I personally find that strict post
conditions (exceptions) are easier to deal with, since the output space is
generally smaller. Because of this, in the cases where failures cannot be
properly handled at a given point in the call-stack, much of the user's
code appears as simple as if the functions couldn't fail at all.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--90e6ba6e84604f43c305168b237c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, May 20, 2015 at 3:23 PM, Nevin Liber <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D"">On 20 May =
2015 at 13:09, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"mailto:jmckesso=
n@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But one thing I&#39;m=
 adamantly against is being forced to use error codes. They should be <i>op=
tional</i>, not mandatory. In C++, exceptions are the standard way of signa=
ling errors; I shouldn&#39;t have to deal with error codes unless I choose =
to.<br></div></div></blockquote><div><br></div></span><div>But that is not =
strictly true.</div><div><br></div><div>For instance, set::insert(value_typ=
e const&amp;) returns a pair whose second element tells you whether or not =
the insertion succeeded.</div><div><br></div><div>It&#39;s more about how u=
nusual the failure is, whether it is likely to be handled locally, etc.</di=
v></div></div></div></blockquote><div><br></div><div>I&#39;ve never been a =
fan of classification based on how &quot;usual&quot; or &quot;unusual&quot;=
 something is because that often depends more on usage rather than being kn=
own at the declaration, and even then what is &quot;usual&quot; vs &quot;un=
usual&quot; isn&#39;t a clear line.</div><div><br></div><div>The way I thin=
k about things:</div><div>Exceptions are for when an implementation cannot =
meet a post-condition, but where no invariants are violated. Exceptions do =
not logically change the output space of the function.<br></div><div>Functi=
ons with &quot;errors codes&quot; or that use &quot;expected&quot; actually=
 weaken post-conditions by instead expanding the output space of the functi=
on such that it now includes those failure states.</div><div><br></div><div=
>The choice of which is used mostly depends on practical concerns (i.e. wha=
t ends up being more efficient for an application), and what users consider=
 easier to reason about or to deal with in higher-level code. Regarding wha=
t is easier to reason about and deal with, I personally find that strict po=
st conditions (exceptions) are easier to deal with, since the output space =
is generally smaller. Because of this, in the cases where failures cannot b=
e properly handled at a given point in the call-stack, much of the user&#39=
;s code appears as simple as if the functions couldn&#39;t fail at all.</di=
v></div></div></div>

<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 />

--90e6ba6e84604f43c305168b237c--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 20 May 2015 19:29:54 -0400
Raw View
On 2015-05-20 11:08, Vicente J. Botet Escriba wrote:
> The expected proposal was blocked as the expected proposal was proposing
> an alternative way to report errors and the standard C++ has already
> one: exceptions.

I'd have to reiterate the position taken by others here... exceptions
are horrible. Plenty of code pretends that exceptions don't exist and/or
is built with exceptions disabled. The cognative overhead of catching
exceptions vs. just checking something like a std::expected is high. The
performance cost of [error handling using] exceptions vs. something like
std::expected is high.

The only mechanisms I'm aware of are:

- exceptions (see above)
- C errno (ugh)
- out parameters to receive error/success
- std::optional
- std::expected

Out parameters are inelegant, and IIRC said inelegance was a direct
contribution for the desire for expected. std::optional is closer, but
has no way of communicating *what* went wrong. It's also no accident
that std::expected is something of an extension to std::optional.

IMO the use for std::expected is clear. (Alas, I am not much help
writing a paper.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 20 May 2015 19:29:57 -0400
Raw View
On 2015-05-20 14:09, Nicol Bolas wrote:
> But one thing I'm adamantly against is being forced to use error codes.
> They should be *optional*, not mandatory. In C++, exceptions are the
> standard way of signaling errors; I shouldn't have to deal with error codes
> unless I choose to.

IMNSHO it's *exceptions* that should be optional, not mandatory. I write
C++ for a living *and* as a hobby, and in both cases, rarely if ever use
or deal with exceptions. I'm talking about cases where either I have
turned them off in the compiler and/or have code that would abort if an
exception gets thrown.

Anyway, that's what's great about std::expected... if you just assume it
is always valid, it throws when you try to access it... so (if you want
to use it that way) the only difference between returning a
std::expected and having the function throw in the first place is where
the exception is thrown. In many cases, this change of location is not
even relevant to how you write your code, especially if you just take
the value of the std::expected as soon as it is returned.

Conversely, if exceptions aren't for you, you can treat std::expected
like a pointer - always check it before "dereferencing" and accept that
your program will abort or do some other horrible thing if you fail to
do so and it was invalid - and not have to worry about "those
'exception' things".

(@Matthew F., warning about an unchecked std::exxpected might be a
little much; the programmer might know that an error can't occur, or
might be happy having the program crash if one does... same as we don't
have warnings about possibly dereferencing null pointers. For that
matter, getting such a warning right - i.e. not having false positives -
is infernally hard.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 20 May 2015 19:42:08 -0400
Raw View
On 2015-05-20 16:52, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> Discriminated union (treated as "expected" with N unexpected cases):
> Cons:
> Errors can be silently missed if the return value is not checked (common if
> return is void or there are other side-effects)

I'd like to point out here that this doesn't really apply. If you don't
return a meaningful result, but might return an error, and you *need* to
enforce that the caller checks if an error occurred, then the proper way
to do that is *not* std::expected or something like it, but rather a
class that may-or-may-not contain an error, that keeps an internal state
noting if it has been checked or not, and throws on destruction if it
has not been checked. I've worked with these before, and while it might
be nice to have something to this effect in the STL, I consider it an
orthogonal issue to the cases where std::expected would be used.

(And if you don't need to enforce error checking, then you should be
returning the error directly.)

Of course, having said that, I could imagine something like:

  // Return number of bytes read
  std::checked_expected<size_t, io_error>
  istream::read(char* buffer, size_t max_len);

....where the value itself may or may not be interesting, but it is
desirable to ensure that the result is at least checked for errors.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 20 May 2015 16:56:46 -0700
Raw View
--001a1130d45efb5d4305168c2db7
Content-Type: text/plain; charset=UTF-8

On Wed, May 20, 2015 at 4:42 PM, Matthew Woehlke <
mw_triad@users.sourceforge.net> wrote:

> On 2015-05-20 16:52, 'Matt Calabrese' via ISO C++ Standard - Future
> Proposals wrote:
> > Discriminated union (treated as "expected" with N unexpected cases):
> > Cons:
> > Errors can be silently missed if the return value is not checked (common
> if
> > return is void or there are other side-effects)
>
> I'd like to point out here that this doesn't really apply. If you don't
> return a meaningful result, but might return an error, and you *need* to
> enforce that the caller checks if an error occurred, then the proper way
> to do that is *not* std::expected or something like it, but rather a
> class that may-or-may-not contain an error, that keeps an internal state
> noting if it has been checked or not, and throws on destruction if it
> has not been checked.


I'm not sure I agree. I'm making a comparison of pure use of
expected/discriminated unions to use of exceptions for a particular part of
code -- not necessarily in conjunction with exceptions. Throwing doesn't
really solve the problem, since very often the reason people use "expected"
is either because they can't realistically use exceptions in their
application or because they want control flow to be more explicit.
Reintroducing exceptions is likely not what many of the users want.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a1130d45efb5d4305168c2db7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, May 20, 2015 at 4:42 PM, Matthew Woehlke <span dir=3D"ltr">&lt;=
<a href=3D"mailto:mw_triad@users.sourceforge.net" target=3D"_blank">mw_tria=
d@users.sourceforge.net</a>&gt;</span> wrote:<br><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex">On 2015-05-20 16:52, &#39;Matt Calabrese&#39; via ISO C++ Standard - F=
uture<br>
Proposals wrote:<br>
&gt; Discriminated union (treated as &quot;expected&quot; with N unexpected=
 cases):<br>
&gt; Cons:<br>
&gt; Errors can be silently missed if the return value is not checked (comm=
on if<br>
&gt; return is void or there are other side-effects)<br>
<br>
I&#39;d like to point out here that this doesn&#39;t really apply. If you d=
on&#39;t<br>
return a meaningful result, but might return an error, and you *need* to<br=
>
enforce that the caller checks if an error occurred, then the proper way<br=
>
to do that is *not* std::expected or something like it, but rather a<br>
class that may-or-may-not contain an error, that keeps an internal state<br=
>
noting if it has been checked or not, and throws on destruction if it<br>
has not been checked.</blockquote><div><br></div><div>I&#39;m not sure I ag=
ree. I&#39;m making a comparison of pure use of expected/discriminated unio=
ns to use of exceptions for a particular part of code -- not necessarily in=
 conjunction with exceptions. Throwing doesn&#39;t really solve the problem=
, since very often the reason people use &quot;expected&quot; is either bec=
ause they can&#39;t realistically use exceptions in their application or be=
cause they want control flow to be more explicit. Reintroducing exceptions =
is likely not what many of the users want.</div></div></div></div>

<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 />

--001a1130d45efb5d4305168c2db7--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 20 May 2015 16:58:03 -0700
Raw View
On Wednesday 20 May 2015 12:02:03 Nicol Bolas wrote:
> It is the standard way. The question is whether we should also, in some
> cases, have an alternative. And what that alternative should be.

Sorry, I didn't mean to start a discussion about the merits of exceptions
again.

I'm just going to say that I agree with Nicol's paragraph above. The C++
standard has made a choice for exceptions, that's fine. All I'm asking is that
there should be some alternative in some cases.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 May 2015 17:22:28 -0700 (PDT)
Raw View
------=_Part_4670_1871167727.1432167748865
Content-Type: multipart/alternative;
 boundary="----=_Part_4671_965461021.1432167748865"

------=_Part_4671_965461021.1432167748865
Content-Type: text/plain; charset=UTF-8



On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-20 11:08, Vicente J. Botet Escriba wrote:
> > The expected proposal was blocked as the expected proposal was proposing
> > an alternative way to report errors and the standard C++ has already
> > one: exceptions.
>
> I'd have to reiterate the position taken by others here... exceptions
> are horrible. Plenty of code pretends that exceptions don't exist and/or
> is built with exceptions disabled.


Plenty of code pretends that error code return values don't exist either.
Indeed, that's far more pernicious, because while code can pretend to
ignore exceptions, they will still halt the program. While a dropped error
code will continue merrily along, with the state of the program becoming
increasingly invalid.

The cognative overhead of catching
> exceptions vs. just checking something like a std::expected is high.


.... how, exactly?


> The
> performance cost of [error handling using] exceptions vs. something like
> std::expected is high.
>

.... is it? Are you talking about in the case where an error actually
happens, or the case where the error doesn't happen? How frequently does
the error condition take place?

You can't possibly talk about the performance of something without cover
the actual circumstances of the specific instance. It doesn't matter if the
cost of catching an exception was even 100x the cost of a failed
`expected`... if the exception is only thrown one out of every 10,000
executions.

Not to mention the fact that you pay the `expected` cost all the time.
Every return value gets bigger. When you get the return value, you have to
copy/move it out of the `expected`; not unless you plan on storing it. So
you can forget about eliding return values when you use `expected`; you
have to do a copy/move. Not unless you're going to use the value in-situ.

So I'd say that your statement requires some actual evidence.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_4671_965461021.1432167748865
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05=
-20 11:08, Vicente J. Botet Escriba wrote:
<br>&gt; The expected proposal was blocked as the expected proposal was pro=
posing
<br>&gt; an alternative way to report errors and the standard C++ has alrea=
dy
<br>&gt; one: exceptions.
<br>
<br>I'd have to reiterate the position taken by others here... exceptions
<br>are horrible. Plenty of code pretends that exceptions don't exist and/o=
r
<br>is built with exceptions disabled.</blockquote><div><br>Plenty of code =
pretends that error code return values don't exist either. Indeed, that's f=
ar more pernicious, because while code can pretend to ignore exceptions, th=
ey will still halt the program. While a dropped error code will continue me=
rrily along, with the state of the program becoming increasingly invalid.<b=
r><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The cognative over=
head of catching
<br>exceptions vs. just checking something like a std::expected is high.</b=
lockquote><div><br>... how, exactly?<br>&nbsp;</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;">The
<br>performance cost of [error handling using] exceptions vs. something lik=
e
<br>std::expected is high.
<br></blockquote><div><br>... is it? Are you talking about in the case wher=
e an error actually happens, or the case where the error doesn't happen? Ho=
w frequently does the error condition take place?<br><br>You can't possibly=
 talk about the performance of something without cover the actual circumsta=
nces of the specific instance. It doesn't matter if the cost of catching an=
 exception was even 100x the cost of a failed `expected`... if the exceptio=
n is only thrown one out of every 10,000 executions.<br><br>Not to mention =
the fact that you pay the `expected` cost all the time. Every return value =
gets bigger. When you get the return value, you have to copy/move it out of=
 the `expected`; not unless you plan on storing it. So you can forget about=
 eliding return values when you use `expected`; you have to do a copy/move.=
 Not unless you're going to use the value in-situ.<br><br>So I'd say that y=
our statement requires some actual evidence.<br></div></div>

<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 />

------=_Part_4671_965461021.1432167748865--
------=_Part_4670_1871167727.1432167748865--

.


Author: Christopher Horvath <blackencino@gmail.com>
Date: Wed, 20 May 2015 17:23:04 -0700 (PDT)
Raw View
------=_Part_4926_1762927703.1432167785217
Content-Type: multipart/alternative;
 boundary="----=_Part_4927_694026662.1432167785217"

------=_Part_4927_694026662.1432167785217
Content-Type: text/plain; charset=UTF-8

Hi, I've just joined this group, and this is my first post.

I'm currently using an implementation of expected<T, E> that is a close
match to the proposal, minus a few features.  I work in an environment
where exceptions are disallowed, as they are in most game engines or
real-time software. Whether or not this is a Good Thing is a separate
issue, I think.  Given the starting assumption of not being allowed to use
exceptions (and having to catch & disarm all exceptions from underlying
libraries), here's a list of options as a coder, of which expected<T,E> is
the clear winner:

   - Can't use exceptions, must report errors from function (example: a
   script had a syntax error, causing parser to fail)


   - abort/assert -> this is obviously bad, but what a surprising amount of
      code does
      - if function was void, return a std::pair<bool, std::string> as an
      example error flag/message. if function is not void, return status pair by
      output reference. Same thing could be done with a tuple on return value
      only.
         - This approach suffers from having to return a dummy value in the
         case of an error, which is especially bad if the return type requires work
         or resources to produce
         - This approach does not force user to check results, error can be
         ignored.
      - return expected<MyReturnType, std::string>.
      - No dummy return value needed in error case
         - if error exists and is not checked, calling value() throws
         exception. Although we're trying to avoid this in my scenario, at least
         there's some effect and error does not silently go by as it might with an
         error code.
         - if error exists, "why" is present as a string, or other error
         structure.
         - is clearly visible at call site, so that someone else reading
         the code can clearly see what's going on

An example usage looks like this:
expected<std::unique_ptr<Mesh>, std::string> readMesh(const std::string&
file_name) {
    try {
        // geometry library returns mesh by pointer, throws exception on
error.
        return expected<std::unique_ptr<Mesh>, std::string>{std::unique_ptr<
Mesh>{geometry::readMesh(file_name)}};
    } catch (std::exception& exc) {
        return make_unexpected<std::unique_ptr<Mesh>>(exc.what());
    } catch (...) {
        return make_unexpected<std::unique_ptr<Mesh>>("unknown exception,
cannot load mesh from file: " + file_name);
    }
}

Two features that would make this even better would be:

   -  being able to specify an on_error functional, so that you could
   specify that it should abort rather than use exceptions, for the case where
   exceptions are disallowed at the compilation level.
   - being able to require (optionally) that the status be checked on an
   expected<void, E> before it goes out of scope, or some other mechanism to
   prevent these errors from being ignored.  This would be helpful even with
   non-void expected<T, E> cases where the return value isn't used.

I realize that "if we just used exceptions" much of this would go away -
but even then there's a design question. Does a parsing error count as an
exception? Are there "weak" and "strong" exceptions?  With the expected
approach, a lot of this ambiguity goes away from API design, and especially
from API usage.

I argue that exceptions and expected happily co-exist, and I'm enjoying
using it so far.  It has cleared up a lot of confusion.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_4927_694026662.1432167785217
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi, I've just joined this group, and this is my first post=
..<div><br></div><div>I'm currently using an implementation of expected&lt;T=
, E&gt; that is a close match to the proposal, minus a few features. &nbsp;=
I work in an environment where exceptions are disallowed, as they are in mo=
st game engines or real-time software. Whether or not this is a Good Thing =
is a separate issue, I think. &nbsp;Given the starting assumption of not be=
ing allowed to use exceptions (and having to catch &amp; disarm all excepti=
ons from underlying libraries), here's a list of options as a coder, of whi=
ch expected&lt;T,E&gt; is the clear winner:</div><div><ul><li>Can't use exc=
eptions, must report errors from function (example: a script had a syntax e=
rror, causing parser to fail)</li></ul></div><div><ul><ul><li><span style=
=3D"line-height: normal;">abort/assert -&gt; this is obviously bad, but wha=
t a surprising amount of code does</span></li><li>if function was void, ret=
urn a std::pair&lt;bool, std::string&gt; as an example error flag/message. =
if function is not void, return status pair by output reference. Same thing=
 could be done with a tuple on return value only.</li><ul><li>This approach=
 suffers from having to return a dummy value in the case of an error, which=
 is especially bad if the return type requires work or resources to produce=
</li><li>This approach does not force user to check results, error can be i=
gnored.</li></ul><li>return expected&lt;MyReturnType, std::string&gt;.<br><=
/li><ul><li>No dummy return value needed in error case</li><li>if error exi=
sts and is not checked, calling value() throws exception. Although we're tr=
ying to avoid this in my scenario, at least there's some effect and error d=
oes not silently go by as it might with an error code.</li><li>if error exi=
sts, "why" is present as a string, or other error structure.</li><li>is cle=
arly visible at call site, so that someone else reading the code can clearl=
y see what's going on</li></ul></ul></ul><div>An example usage looks like t=
his:</div></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(1=
87, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #000;" class=3D"styled-by-prettify">expected</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">unique_ptr</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled=
-by-prettify">Mesh</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&gt;,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> readMesh</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> file_name</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">try=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nb=
sp; </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// geo=
metry library returns mesh by pointer, throws exception on error.</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &n=
bsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> e=
xpected</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">unique_ptr</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Mesh</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&gt;,</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
unique_ptr</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Mesh</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">geometry</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">readMesh</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">file_name</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">)}};</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">catch</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">exception</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> exc</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> make_unexpected</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">unique_ptr</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Mesh</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&gt;&gt;(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">exc</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">what<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">());</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">catch</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(...)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> make_unexpected</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">unique_ptr</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Mesh</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&gt;&gt;(</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y">"unknown exception, cannot load mesh from file: "</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> file_name</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span></div></code></div><div><br></div><div>Two features that w=
ould make this even better would be:</div><div><ul><li>&nbsp;being able to =
specify an on_error functional, so that you could specify that it should ab=
ort rather than use exceptions, for the case where exceptions are disallowe=
d at the compilation level.<br></li><li>being able to require (optionally) =
that the status be checked on an expected&lt;void, E&gt; before it goes out=
 of scope, or some other mechanism to prevent these errors from being ignor=
ed. &nbsp;This would be helpful even with non-void expected&lt;T, E&gt; cas=
es where the return value isn't used.</li></ul><div><span style=3D"line-hei=
ght: 17px;">I realize that "if we just used exceptions" much of this would =
go away - but even then there's a design question. Does a parsing error cou=
nt as an exception? Are there "weak" and "strong" exceptions? &nbsp;With th=
e expected approach, a lot of this ambiguity goes away from API design, and=
 especially from API usage.</span></div></div><div><span style=3D"line-heig=
ht: 17px;"><br></span></div><div><span style=3D"line-height: 17px;">I argue=
 that exceptions and expected happily co-exist, and I'm enjoying using it s=
o far. &nbsp;It has cleared up a lot of confusion.</span></div></div>

<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 />

------=_Part_4927_694026662.1432167785217--
------=_Part_4926_1762927703.1432167785217--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 21 May 2015 08:49:16 +0200
Raw View
This is a multi-part message in MIME format.
--------------010005050104060206010901
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 21/05/15 01:58, Thiago Macieira a =C3=A9crit :
> On Wednesday 20 May 2015 12:02:03 Nicol Bolas wrote:
>> It is the standard way. The question is whether we should also, in some
>> cases, have an alternative. And what that alternative should be.
> Sorry, I didn't mean to start a discussion about the merits of exceptions
> again.
>
> I'm just going to say that I agree with Nicol's paragraph above. The C++
> standard has made a choice for exceptions, that's fine. All I'm asking is=
 that
> there should be some alternative in some cases.
>
The monad error expected<T> is not an alternative to exceptions, but to=20
the other ways used to report errors without exceptions. Either we have=20
non of them either we need to select a better way.

If someone wants to discuss the merits/demerits of exceptions, could=20
s/he start the discussion on a new thread, please?

Thanks,
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/.

--------------010005050104060206010901
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 text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 21/05/15 01:58, Thiago Macieira a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote cite=3D"mid:1749695.FCqFeZNAuF@tjmaciei-mobl4" type=3D"cite=
">
      <pre wrap=3D"">On Wednesday 20 May 2015 12:02:03 Nicol Bolas wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">It is the standard way. The question is whether we s=
hould also, in some=20
cases, have an alternative. And what that alternative should be.
</pre>
      </blockquote>
      <pre wrap=3D"">
Sorry, I didn't mean to start a discussion about the merits of exceptions=
=20
again.

I'm just going to say that I agree with Nicol's paragraph above. The C++=20
standard has made a choice for exceptions, that's fine. All I'm asking is t=
hat=20
there should be some alternative in some cases.

</pre>
    </blockquote>
    <font size=3D"+1">The monad error expected&lt;T&gt; is not an
      alternative to exceptions, but to the other ways used to report
      errors without exceptions. Either we have non of them either we
      need to select a better way.<br>
      <br>
      If someone wants to discuss the merits/demerits of exceptions, </font=
>could
    s/he start the discussion on a new thread, please?<br>
    <br>
    Thanks,<br>
    Vicente<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 />

--------------010005050104060206010901--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 21 May 2015 09:06:40 +0200
Raw View
This is a multi-part message in MIME format.
--------------070205020205060903060702
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 20/05/15 20:09, Nicol Bolas a =C3=A9crit :
> On Wednesday, May 20, 2015 at 2:05:31 PM UTC-4, Tony V E wrote:
>
>     On Wed, May 20, 2015 at 11:08 AM, Vicente J. Botet Escriba
>     <vicent...@wanadoo.fr <javascript:>> wrote:
>
>         Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>
>>         I think at this point, we should focus on getting the core
>>         feature: parsing strings via string_view. And those many
>>         malign the FileSystem TS solution, it /is/ prior art on
>>         dealing with error codes in standard library C++.
>>
>         I don't share the FileSystem design to report errors. I have
>         used it in Boost.Chrono, and it really doesn't scale. It is
>         difficult to say it is prior art when we include it in the FS
>         TS. For me, it is the temporary C++ standard way of defining
>         interfaces that report errors without using exceptions until
>         we have a better way.
>
>         Vicente
>
>
>
>     Yes I really think we should use FS as an example of "there must
>     be a better way to do this".  To me that is either:
>
>     - just use exceptions
>     or
>     - something like expected<>
>
>     The FS should have half as many functions as it currently has.  I
>     hope that is fixed before standardization.
>
>
> I personally have no complaints about the filesystem's method of doing=20
> error codes. But I also wouldn't be adverse to seeing `expected` used=20
> instead of error code parameter outputs.
>
> But one thing I'm adamantly against is being forced to use error=20
> codes. They should be /optional/, not mandatory. In C++, exceptions=20
> are the standard way of signaling errors; I shouldn't have to deal=20
> with error codes unless I choose to.
>
> So I would say that filesystem should keep the same number of=20
> functions. Either that, or it shouldn't support error codes at all.
>

I understand that some of us want to be able to use exceptions instead=20
or error codes and that the code is as readable as it can.
The idiom

     auto i =3D return_expected().value();

to throw an exception, is not as readable as without the call to value().

I have not a solution to the duplication of functions and expected=20
doesn't try to solve it. I we need to have an interface that avoids=20
exceptions, expected is a good candidate.

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/.

--------------070205020205060903060702
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 text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 20/05/15 20:09, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:d46ce7c8-9a92-4f0c-9b80-5a5d0db818ee@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Wednesday, May 20, 2015 at 2:05:31 PM UTC-4,
        Tony V E wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div dir=3D"ltr">
            <div>
              <div class=3D"gmail_quote">On Wed, May 20, 2015 at 11:08 AM,
                Vicente J. Botet Escriba <span dir=3D"ltr">&lt;<a
                    moz-do-not-send=3D"true" href=3D"javascript:"
                    target=3D"_blank" gdf-obfuscated-mailto=3D"NrolvPzEMuEJ=
"
                    rel=3D"nofollow"
                    onmousedown=3D"this.href=3D'javascript:';return true;"
                    onclick=3D"this.href=3D'javascript:';return true;">vice=
nt...@wanadoo.fr</a>&gt;</span>
                wrote:<br>
                <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
                  .8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
                    <div>Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit=C2=A0:=
<br>
                    </div>
                    <br>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr">
                        <div>I think at this point, we should focus on
                          getting the core feature: parsing strings via
                          string_view. And those many malign the
                          FileSystem TS solution, it <i>is</i> prior
                          art on dealing with error codes in standard
                          library C++.<br>
                        </div>
                      </div>
                      <br>
                    </blockquote>
                    I don't share the FileSystem design to report
                    errors. I have used it in Boost.Chrono, and it
                    really doesn't scale. It is difficult to say it is
                    prior art when we include it in the FS TS. For me,
                    it is the temporary C++ standard way of defining
                    interfaces that report errors without using
                    exceptions until we have a better way.<span><font
                        color=3D"#888888"><br>
                        <br>
                        Vicente<br>
                      </font></span></div>
                </blockquote>
                <div><br>
                  <br>
                </div>
                <div>Yes I really think we should use FS as an example
                  of "there must be a better way to do this".=C2=A0 To me
                  that is either:<br>
                  <br>
                </div>
                <div>- just use exceptions<br>
                </div>
                <div>or<br>
                </div>
                <div>- something like expected&lt;&gt;<br>
                  <br>
                </div>
                <div>The FS should have half as many functions as it
                  currently has.=C2=A0 I hope that is fixed before
                  standardization.<br>
                </div>
              </div>
            </div>
          </div>
        </blockquote>
        <div><br>
          I personally have no complaints about the filesystem's method
          of doing error codes. But I also wouldn't be adverse to seeing
          `expected` used instead of error code parameter outputs.<br>
          <br>
          But one thing I'm adamantly against is being forced to use
          error codes. They should be <i>optional</i>, not mandatory.
          In C++, exceptions are the standard way of signaling errors; I
          shouldn't have to deal with error codes unless I choose to.<br>
          <br>
          So I would say that filesystem should keep the same number of
          functions. Either that, or it shouldn't support error codes at
          all.<br>
        </div>
      </div>
      <br>
    </blockquote>
    <br>
    I understand that some of us want to be able to use exceptions
    instead or error codes and that the code is as readable as it can.<br>
    The idiom <br>
    <br>
    =C2=A0=C2=A0=C2=A0 auto i =3D return_expected().value();<br>
    <br>
    to throw an exception, is not as readable as without the call to
    value(). <br>
    <br>
    I have not a solution to the duplication of functions and expected
    doesn't try to solve it. I we need to have an interface that avoids
    exceptions, expected is a good candidate.<br>
    <br>
    Vicente <br>
    <br>
    <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 />

--------------070205020205060903060702--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Thu, 21 May 2015 04:33:14 -0700 (PDT)
Raw View
------=_Part_5194_121760992.1432207994882
Content-Type: multipart/alternative;
 boundary="----=_Part_5195_2032560600.1432207994882"

------=_Part_5195_2032560600.1432207994882
Content-Type: text/plain; charset=UTF-8

On Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bolas wrote:

> But one thing I'm adamantly against is being forced to use error codes.
> They should be *optional*, not mandatory. In C++, exceptions are the
> standard way of signaling errors; I shouldn't have to deal with error codes
> unless I choose to.
>

Others are against being forced to use exceptions.. They should be
*optional*, not mandatory. Are exceptions the standard for errors? I don't
know. What's an error?

For example AFAIK iostream doesn't throw if it can't open a file.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5195_2032560600.1432207994882
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bola=
s wrote:<div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>But one thing I'm adamantly against is being forced to use error codes=
.. They should be <i>optional</i>, not mandatory. In C++, exceptions are the=
 standard way of signaling errors; I shouldn't have to deal with error code=
s unless I choose to.<br></div></div></blockquote><div><br></div><div>Other=
s are against being forced to use exceptions.. They should be&nbsp;<i>optio=
nal</i>, not mandatory. Are exceptions the standard for errors? I don't kno=
w. What's an error?</div></div><div><br></div><div>For example AFAIK iostre=
am doesn't throw if it can't open a file.</div><div><br></div><div><br></di=
v></div>

<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 />

------=_Part_5195_2032560600.1432207994882--
------=_Part_5194_121760992.1432207994882--

.


Author: Patrice Roy <patricer@gmail.com>
Date: Thu, 21 May 2015 08:13:10 -0400
Raw View
--001a11355f52936ea40516967737
Content-Type: text/plain; charset=UTF-8

There are legitimate use cases for both. Given the importance of
constructors, exceptions are not going to go away, and this does not make
tools like optional or expected any less useful in their own right.

For parsing, I think comparing I/O examples in C++ (streams signal problems
through error states, unless the client code explicitly requests this to be
done through exceptions) and in Java (mandatory exception checking) give us
a clue that systematic exception checking leads to much more complex client
code even in the simplest cases (I'll spare you examples even though they
really make C++ shine :) ). Setting streams in such a way as to signal
problems through exceptions, though, might be appropriate in some
situations. My personal preference would be to follow the same path: errors
in general, expections if explicitly requested by the client code. It would
seem to be philosophically in line with existing practice.


2015-05-21 7:33 GMT-04:00 Olaf van der Spek <olafvdspek@gmail.com>:

> On Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bolas wrote:
>
>> But one thing I'm adamantly against is being forced to use error codes.
>> They should be *optional*, not mandatory. In C++, exceptions are the
>> standard way of signaling errors; I shouldn't have to deal with error codes
>> unless I choose to.
>>
>
> Others are against being forced to use exceptions.. They should be
> *optional*, not mandatory. Are exceptions the standard for errors? I
> don't know. What's an error?
>
> For example AFAIK iostream doesn't throw if it can't open a file.
>
>
>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11355f52936ea40516967737
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>There are legitimate use cases for both. Given the im=
portance of constructors, exceptions are not going to go away, and this doe=
s not make tools like optional or expected any less useful in their own rig=
ht.<br><br></div>For parsing, I think comparing I/O examples in C++ (stream=
s signal problems through error states, unless the client code explicitly r=
equests this to be done through exceptions) and in Java (mandatory exceptio=
n checking) give us a clue that systematic exception checking leads to much=
 more complex client code even in the simplest cases (I&#39;ll spare you ex=
amples even though they really make C++ shine :) ). Setting streams in such=
 a way as to signal problems through exceptions, though, might be appropria=
te in some situations. My personal preference would be to follow the same p=
ath: errors in general, expections if explicitly requested by the client co=
de. It would seem to be philosophically in line with existing practice.<br>=
<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-05=
-21 7:33 GMT-04:00 Olaf van der Spek <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:olafvdspek@gmail.com" target=3D"_blank">olafvdspek@gmail.com</a>&gt;</spa=
n>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On =
Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bolas wrote:</span><div>=
<span class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><=
div>But one thing I&#39;m adamantly against is being forced to use error co=
des. They should be <i>optional</i>, not mandatory. In C++, exceptions are =
the standard way of signaling errors; I shouldn&#39;t have to deal with err=
or codes unless I choose to.<br></div></div></blockquote><div><br></div></s=
pan><div>Others are against being forced to use exceptions.. They should be=
=C2=A0<i>optional</i>, not mandatory. Are exceptions the standard for error=
s? I don&#39;t know. What&#39;s an error?</div></div><div><br></div><div>Fo=
r example AFAIK iostream doesn&#39;t throw if it can&#39;t open a file.</di=
v><div><br></div><div><br></div></div><div class=3D"HOEnZb"><div class=3D"h=
5">

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<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 />

--001a11355f52936ea40516967737--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 21 May 2015 06:19:41 -0700 (PDT)
Raw View
------=_Part_5356_1161572761.1432214381135
Content-Type: multipart/alternative;
 boundary="----=_Part_5357_1927042897.1432214381135"

------=_Part_5357_1927042897.1432214381135
Content-Type: text/plain; charset=UTF-8

On Thursday, May 21, 2015 at 7:33:14 AM UTC-4, Olaf van der Spek wrote:
>
> On Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bolas wrote:
>
>> But one thing I'm adamantly against is being forced to use error codes.
>> They should be *optional*, not mandatory. In C++, exceptions are the
>> standard way of signaling errors; I shouldn't have to deal with error codes
>> unless I choose to.
>>
>
> Others are against being forced to use exceptions..
>

I don't have to care what they're against, because exceptions are *standard*
..

Are exceptions the standard for errors?
>

Yes, they are; just look at the C++ standard library. They are not always
be used in every case; in accord with the iostream library's seeming desire
to make the wrong decision at every turn, they make them optional. But
they're clearly the primary way errors get reported in the standard library.

Whether you like exceptions or not, the fact that they are the standard
mechanism for reporting errors in the C++ standard is not open for debate.
Virtually all new libraries are designed around them, and any error code
API is available only available as an option, not the default.

From the standard: "Class `error_code` is an adjunct to error reporting by
exception."

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5357_1927042897.1432214381135
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, May 21, 2015 at 7:33:14 AM UTC-4, Olaf van de=
r Spek wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
On Wednesday, May 20, 2015 at 8:09:20 PM UTC+2, Nicol Bolas wrote:<div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But one thing I'm=
 adamantly against is being forced to use error codes. They should be <i>op=
tional</i>, not mandatory. In C++, exceptions are the standard way of signa=
ling errors; I shouldn't have to deal with error codes unless I choose to.<=
br></div></div></blockquote><div><br></div><div>Others are against being fo=
rced to use exceptions..</div></div></div></blockquote><div><br>I don't hav=
e to care what they're against, because exceptions are <i>standard</i>.<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v><div> Are exceptions the standard for errors?</div></div></div></blockquo=
te><div><br>Yes, they are; just look at the C++ standard library. They are =
not always be used in every case; in accord with the iostream library's see=
ming desire to make the wrong decision at every turn, they make them option=
al. But they're clearly the primary way errors get reported in the standard=
 library.<br><br>Whether you like exceptions or not, the fact that they are=
 the standard mechanism for reporting errors in the C++ standard is not ope=
n for debate. Virtually all new libraries are designed around them, and any=
 error code API is available only available as an option, not the default.<=
br><br>From the standard: "Class `error_code` is an adjunct to error report=
ing by exception."<br></div></div>

<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 />

------=_Part_5357_1927042897.1432214381135--
------=_Part_5356_1161572761.1432214381135--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 10:24:59 -0400
Raw View
On 2015-05-20 19:56, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> On Wed, May 20, 2015 at 4:42 PM, Matthew Woehlke wrote:
>> On 2015-05-20 16:52, 'Matt Calabrese' via ISO C++ Standard - Future
>> Proposals wrote:
>>> Discriminated union (treated as "expected" with N unexpected cases):
>>> Cons:
>>> Errors can be silently missed if the return value is not checked (common
>>> if return is void or there are other side-effects)
>>
>> I'd like to point out here that this doesn't really apply. If you don't
>> return a meaningful result, but might return an error, and you *need* to
>> enforce that the caller checks if an error occurred, then the proper way
>> to do that is *not* std::expected or something like it, but rather a
>> class that may-or-may-not contain an error, that keeps an internal state
>> noting if it has been checked or not, and throws on destruction if it
>> has not been checked.
>
> I'm not sure I agree. I'm making a comparison of pure use of
> expected/discriminated unions to use of exceptions for a particular part of
> code -- not necessarily in conjunction with exceptions. Throwing doesn't
> really solve the problem, since very often the reason people use "expected"
> is either because they can't realistically use exceptions in their
> application or because they want control flow to be more explicit.
> Reintroducing exceptions is likely not what many of the users want.

The difference in this case is that if your program is written
correctly, the exception is never thrown. The exception in this case is
not the original error, but failure to check for the error, which is not
a runtime error, but a coding error, i.e. "something bad happened *and*
nothing paid attention".

In fact, one can argue that this would be a compile error. (The counter
argument is that you want to write code where you assume that errors
never occur, i.e. you don't want to have to bother checking for them,
and you don't mind if the program simply aborts if one does.)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 10:53:05 -0400
Raw View
On 2015-05-20 20:22, Nicol Bolas wrote:
> On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
>> The cognative overhead of catching
>> exceptions vs. just checking something like a std::expected is high.
>
> ... how, exactly?

  auto result = parse(input);

  if (result)
    do_something(*result);

  do_something_else();

  if (result)
    do_something_again(*result);

- vs -

  T result; // grr, can't use auto
  auto is_valid = false;

  try {
    result = parse(input);
    is_valid = true;
  }
  catch(/* what goes here? */) { /* don't care */ }

  if (is_valid)
    do_something(result);

  do_something_else();

  if (is_valid)
    do_something_again(*result);

So... a simple if() vs. a try-catch that requires me to know what I am
supposed to be catching and potentially messes up my scope and/or
control flow.

> You can't possibly talk about the performance of something without cover
> the actual circumstances of the specific instance. It doesn't matter if the
> cost of catching an exception was even 100x the cost of a failed
> `expected`... if the exception is only thrown one out of every 10,000
> executions.

Yes, but what if failure is frequent? In file parsing, this might not be
unusual. For that matter, what if I'm parsing a file whose fields may or
may not be numbers, and the way I determine that is by trying to parse
the field as a number and seeing if it succeeds? (I can certainly
imagine this being more efficient than parsing the field twice, once to
see if it "looks like" a number, then again to get the value... hoping
on the second pass that I didn't miss something.)

This reminds me of something I saw recently (not sure if it was this
group) about not spending resources on malicious actions... but that's
exactly what exceptions do; turn the case of bad input into the most
expensive code path.

> Not to mention the fact that you pay the `expected` cost all the time.
> Every return value gets bigger. When you get the return value, you have to
> copy/move it out of the `expected`; not unless you plan on storing it. So
> you can forget about eliding return values when you use `expected`; you
> have to do a copy/move. Not unless you're going to use the value in-situ.
>
> So I'd say that your statement requires some actual evidence.

I'd say that for your statement also. I could easily write a highly
optimized `expected<T, exception_ptr>` whose size is only sizeof(T) +
sizeof(void*) and whose move ctor consists of a POD assignment of a T
and a void*, and a clear of a void*. (And the compiler ought to be able
to optimize away the dtor of the old instance.) *And* you're asserting
that RVO is not possible for that? (Why?)

I can write an even better `expected<T, ErrorEnum>`... it's standard
layout and trivially copyable with size sizeof(T) + sizeof(ErrorEnum).

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 May 2015 08:34:27 -0700 (PDT)
Raw View
------=_Part_577_939066688.1432222467126
Content-Type: multipart/alternative;
 boundary="----=_Part_578_1036503413.1432222467127"

------=_Part_578_1036503413.1432222467127
Content-Type: text/plain; charset=UTF-8



On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-20 20:22, Nicol Bolas wrote:
> > On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
> >> The cognative overhead of catching
> >> exceptions vs. just checking something like a std::expected is high.
> >
> > ... how, exactly?
>
>   auto result = parse(input);
>
>   if (result)
>     do_something(*result);
>
>   do_something_else();
>
>   if (result)
>     do_something_again(*result);
>
> - vs -
>
>   T result; // grr, can't use auto
>   auto is_valid = false;
>
>   try {
>     result = parse(input);
>     is_valid = true;
>   }
>   catch(/* what goes here? */) { /* don't care */ }
>
>   if (is_valid)
>     do_something(result);
>
>   do_something_else();
>
>   if (is_valid)
>     do_something_again(*result);
>
> So... a simple if() vs. a try-catch that requires me to know what I am
> supposed to be catching and potentially messes up my scope and/or
> control flow.
>
> > You can't possibly talk about the performance of something without cover
> > the actual circumstances of the specific instance. It doesn't matter if
> the
> > cost of catching an exception was even 100x the cost of a failed
> > `expected`... if the exception is only thrown one out of every 10,000
> > executions.
>
> Yes, but what if failure is frequent? In file parsing, this might not be
> unusual. For that matter, what if I'm parsing a file whose fields may or
> may not be numbers, and the way I determine that is by trying to parse
> the field as a number and seeing if it succeeds? (I can certainly
> imagine this being more efficient than parsing the field twice, once to
> see if it "looks like" a number, then again to get the value... hoping
> on the second pass that I didn't miss something.)
>

It really depends on what you're trying to do.

If failure is frequent and you need to handle each individual failure
differently then exceptions get in the way. Its much easier (and also
possibly more efficient) to check a return code with if() instead of
setting up separate try/catch blocks around each call. The specific error
handling for each situation is also localized to where the error occurs,
improving readability.

The one case where I've seen exceptions really shine is when you have an
all or nothing situation where you want to try a bunch of steps and just
bail out completely the same way if any one of them fails. For example you
want to do a bunch of file IO routines, or parse a text file, or do a
series of system calls, etc..

I've had to write plenty of systems C code which do system call after
system call and have to carefully check the return value of each one (not
to mention careful use of goto for resource cleanup since we don't have
RAII!). Its extremely painful and usually you end up writing a macro
wrapper which will call the function, check for failure, and
log/return/goto if it failed . Having exceptions with a try/catch block
around the whole series of calls really improves this situation
dramatically because the error handling is identical for each call and with
try/catch you can specify it only once.


> This reminds me of something I saw recently (not sure if it was this
> group) about not spending resources on malicious actions... but that's
> exactly what exceptions do; turn the case of bad input into the most
> expensive code path.
>

If the case of bad input is rare (exceptional), then this can actually be a
good thing. If bad input is common, then you might be pessimizing your code.


>
> > Not to mention the fact that you pay the `expected` cost all the time.
> > Every return value gets bigger. When you get the return value, you have
> to
> > copy/move it out of the `expected`; not unless you plan on storing it.
> So
> > you can forget about eliding return values when you use `expected`; you
> > have to do a copy/move. Not unless you're going to use the value
> in-situ.
>

I think this problem exists for any function that returns multiple values,
whether its struct like (i.e. tuple, pair, array)  or union like (i.e.
variant, optional, expected).

It might still be possible for the compiler to optimize in some cases:

auto x = foo().value();

In the above example, since the expected object is never actually kept
around and is guaranteed to contain a value if it didn't throw, the
optimizer ostensibly could elide a move and make local variable x just
reference the memory used by the expected object returned by foo.

If you're just using the value locally and then throwing it away, you can
create a reference
auto exp = foo();
if(!exp) {
  //handle error
}
auto& val = exp.value();

If you're storing the value somewhere externally then all bets are off, you
have to pay for at least a move.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_578_1036503413.1432222467127
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05=
-20 20:22, Nicol Bolas wrote:
<br>&gt; On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wr=
ote:
<br>&gt;&gt; The cognative overhead of catching=20
<br>&gt;&gt; exceptions vs. just checking something like a std::expected is=
 high.
<br>&gt;=20
<br>&gt; ... how, exactly?
<br>
<br>&nbsp; auto result =3D parse(input);
<br>
<br>&nbsp; if (result)
<br>&nbsp; &nbsp; do_something(*result);
<br>
<br>&nbsp; do_something_else();
<br>
<br>&nbsp; if (result)
<br>&nbsp; &nbsp; do_something_again(*result);
<br>
<br>- vs -
<br>
<br>&nbsp; T result; // grr, can't use auto
<br>&nbsp; auto is_valid =3D false;
<br>
<br>&nbsp; try {
<br>&nbsp; &nbsp; result =3D parse(input);
<br>&nbsp; &nbsp; is_valid =3D true;
<br>&nbsp; }
<br>&nbsp; catch(/* what goes here? */) { /* don't care */ }
<br>
<br>&nbsp; if (is_valid)
<br>&nbsp; &nbsp; do_something(result);
<br>
<br>&nbsp; do_something_else();
<br>
<br>&nbsp; if (is_valid)
<br>&nbsp; &nbsp; do_something_again(*result);
<br>
<br>So... a simple if() vs. a try-catch that requires me to know what I am
<br>supposed to be catching and potentially messes up my scope and/or
<br>control flow.
<br>
<br>&gt; You can't possibly talk about the performance of something without=
 cover=20
<br>&gt; the actual circumstances of the specific instance. It doesn't matt=
er if the=20
<br>&gt; cost of catching an exception was even 100x the cost of a failed=
=20
<br>&gt; `expected`... if the exception is only thrown one out of every 10,=
000=20
<br>&gt; executions.
<br>
<br>Yes, but what if failure is frequent? In file parsing, this might not b=
e
<br>unusual. For that matter, what if I'm parsing a file whose fields may o=
r
<br>may not be numbers, and the way I determine that is by trying to parse
<br>the field as a number and seeing if it succeeds? (I can certainly
<br>imagine this being more efficient than parsing the field twice, once to
<br>see if it "looks like" a number, then again to get the value... hoping
<br>on the second pass that I didn't miss something.)
<br></blockquote><div><br>It really depends on what you're trying to do.&nb=
sp; <br><br>If failure is frequent and you need to handle each individual f=
ailure differently then exceptions get in the way. Its much easier (and als=
o possibly more efficient) to check a return code with if() instead of sett=
ing up separate try/catch blocks around each call. The specific error handl=
ing for each situation is also localized to where the error occurs, improvi=
ng readability.<br><br>The one case where I've seen exceptions really shine=
 is when you have an all or nothing situation where you want to try a bunch=
 of steps and just bail out completely the same way if any one of them fail=
s. For example you want to do a bunch of file IO routines, or parse a text =
file, or do a series of system calls, etc.. <br><br>I've had to write plent=
y of systems C code which do system call after system call and have to care=
fully check the return value of each one (not to mention careful use of got=
o for resource cleanup since we don't have RAII!). Its extremely painful an=
d usually you end up writing a macro wrapper which will call the function, =
check for failure, and log/return/goto if it failed . Having exceptions wit=
h a try/catch block around the whole series of calls really improves this s=
ituation dramatically because the error handling is identical for each call=
 and with try/catch you can specify it only once.<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;">
<br>This reminds me of something I saw recently (not sure if it was this
<br>group) about not spending resources on malicious actions... but that's
<br>exactly what exceptions do; turn the case of bad input into the most
<br>expensive code path.
<br></blockquote><div><br>If the case of bad input is rare (exceptional), t=
hen this can actually be a good thing. If bad input is common, then you mig=
ht be pessimizing your code.<br>&nbsp;</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">
<br>&gt; Not to mention the fact that you pay the `expected` cost all the t=
ime.=20
<br>&gt; Every return value gets bigger. When you get the return value, you=
 have to=20
<br>&gt; copy/move it out of the `expected`; not unless you plan on storing=
 it. So=20
<br>&gt; you can forget about eliding return values when you use `expected`=
; you=20
<br>&gt; have to do a copy/move. Not unless you're going to use the value i=
n-situ.
<br></blockquote><div><br>I think this problem exists for any function that=
 returns multiple values, whether its struct like (i.e. tuple, pair, array)=
&nbsp; or union like (i.e. variant, optional, expected).<br><br>It might st=
ill be possible for the compiler to optimize in some cases:<br><br><div cla=
ss=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap:=
 break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">().</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">value</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span></div></code></div><br>In the above example, since t=
he expected object is never actually kept around and is guaranteed to conta=
in a value if it didn't throw, the optimizer ostensibly could elide a move =
and make local variable x just reference the memory used by the expected ob=
ject returned by foo.<br><br>If you're just using the value locally and the=
n throwing it away, you can create a reference<br><div class=3D"prettyprint=
" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187=
, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> exp </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>if</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(!</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">exp</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">//handle error</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
val </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> exp</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">value</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>If you=
're storing the value somewhere externally then all bets are off, you have =
to pay for at least a move.<br>&nbsp;</div></div>

<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 />

------=_Part_578_1036503413.1432222467127--
------=_Part_577_939066688.1432222467126--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 11:47:55 -0400
Raw View
On 2015-05-21 11:34, Matthew Fioravante wrote:
> On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Woehlke wrote:
>> On 2015-05-20 20:22, Nicol Bolas wrote:
>>> On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
>>>> The cognative overhead of catching
>>>> exceptions vs. just checking something like a std::expected is high.
>>>
>>> ... how, exactly?
>> [...]
>>> You can't possibly talk about the performance of something without cover
>>> the actual circumstances of the specific instance. It doesn't matter if
>>> the cost of catching an exception was even 100x the cost of a
>>> failed `expected`... if the exception is only thrown one out of
>>> every 10,000 executions.
>>
>> Yes, but what if failure is frequent?
>
> It really depends on what you're trying to do.
>
> If failure is frequent and you need to handle each individual failure
> differently then exceptions get in the way. Its much easier (and also
> possibly more efficient) to check a return code with if() instead of
> setting up separate try/catch blocks around each call. The specific error
> handling for each situation is also localized to where the error occurs,
> improving readability.

I could point out that you can individually wrap each call in its own
try/catch, but as I was trying to illustrate, that's likely to be
detrimental to readability :-).

Actually, you caught the point I missed in my previous mail, responding
to Nicol's question about cognative load... an if() checking the result
at the point where you obtain it is easy to follow. Having to dig down
an unknown number of layers of control flow to find an enclosing
try/catch is much, much harder. Especially when exceptions start making
it further up the stack before being caught, possibly in many different
and widely varying locations.

> The one case where I've seen exceptions really shine is when you have an
> all or nothing situation where you want to try a bunch of steps and just
> bail out completely the same way if any one of them fails. For example you
> want to do a bunch of file IO routines, or parse a text file, or do a
> series of system calls, etc..

....so just don't check if your std::expected is valid :-).

This (not talking to you - Matthew F. - specifically any more) is why I
don't understand why the exception-worshippers object so strongly to
std::expected. If you prefer exceptions, *you can have exceptions*,
almost trivially. They just aren't *forced* on you.

Conversely, the burden of forcing exceptions on those of us that don't
want exceptions is much heavier.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 21 May 2015 09:35:43 -0700 (PDT)
Raw View
------=_Part_5543_2079725137.1432226143831
Content-Type: multipart/alternative;
 boundary="----=_Part_5544_1496538987.1432226143831"

------=_Part_5544_1496538987.1432226143831
Content-Type: text/plain; charset=UTF-8

On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-20 20:22, Nicol Bolas wrote:
> > On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
> >> The cognative overhead of catching
> >> exceptions vs. just checking something like a std::expected is high.
> >
> > ... how, exactly?
>
>   auto result = parse(input);
>
>   if (result)
>     do_something(*result);
>
>   do_something_else();
>
>   if (result)
>     do_something_again(*result);
>
> - vs -
>
>   T result; // grr, can't use auto
>   auto is_valid = false;
>
>   try {
>     result = parse(input);
>     is_valid = true;
>   }
>   catch(/* what goes here? */) { /* don't care */ }
>
>   if (is_valid)
>     do_something(result);
>
>   do_something_else();
>
>   if (is_valid)
>     do_something_again(*result);
>

Nobody writes exception handling code like that, for the simple and obvious
reason that nobody would want to.

You'd do this:

try
{
  auto result = parse(input);
  do_something(result);
  do_something_else();
  do_something_again(result);
}
catch(<insert exception here>)
{
  do_something_else();
}

Alternatively, you could simply move `do_something_else` outside of the
condition, unless there's a reason why `do_something_else` absolutely must
come before do_something_again`. In which case, maybe "else" shouldn't be
part of the name ;)

Also, what happens if you need to handle different kind of errors? After
all, `parse` might fail for multiple reasons. The input could fail to
match. Or the input couldn't be read from the stream (aka: a filesystem
error). The latter requires that you terminate the parsing operation, which
must be handled at a higher level than this mere function.

What does your code look like then? How do you locally handle the
input-failure error, while still propagating the filesystem error to the
code that can actually terminate the parse operation?


> So... a simple if() vs. a try-catch that requires me to know what I am
> supposed to be catching and potentially messes up my scope and/or
> control flow.


Ignoring the inaccuracy of the latter clause, knowing what you are supposed
to catch is... well, par for the course. See the above scenario, where the
reason for the failure materially affects how the user should react to it.

> You can't possibly talk about the performance of something without cover
> > the actual circumstances of the specific instance. It doesn't matter if
> the
> > cost of catching an exception was even 100x the cost of a failed
> > `expected`... if the exception is only thrown one out of every 10,000
> > executions.
>
> Yes, but what if failure is frequent? In file parsing, this might not be
> unusual. For that matter, what if I'm parsing a file whose fields may or
> may not be numbers, and the way I determine that is by trying to parse
> the field as a number and seeing if it succeeds?


Then that would be a matter of your parsing interface. Such a function
might be called "parse_possible_integer" or whatever. The function, by its
contract with the caller, recognizes the possibility that the text may not
be parsable as an integer.

There's a conceptual difference between "convert this text to an integer"
and "if this text is an integer, convert it". These are two different
functions.

This reminds me of something I saw recently (not sure if it was this
> group) about not spending resources on malicious actions... but that's
> exactly what exceptions do; turn the case of bad input into the most
> expensive code path.
>

"Bad input" is not necessarily "malicious". Indeed, it rarely is.

> Not to mention the fact that you pay the `expected` cost all the time.
> > Every return value gets bigger. When you get the return value, you have
> to
> > copy/move it out of the `expected`; not unless you plan on storing it.
> So
> > you can forget about eliding return values when you use `expected`; you
> > have to do a copy/move. Not unless you're going to use the value
> in-situ.
> >
> > So I'd say that your statement requires some actual evidence.
>
> I'd say that for your statement also. I could easily write a highly
> optimized `expected<T, exception_ptr>` whose size is only sizeof(T) +
> sizeof(void*) and whose move ctor consists of a POD assignment of a T
> and a void*, and a clear of a void*.


.... so? That's still more expensive than elision. Also, that wasn't the
expense I was talking about. Also, I'm pretty sure `exception_ptr` needs
more than just a pointer.

Also, a "POD assignment of a T" requires that T be a POD (or whatever
you're talking about. I think you mean "trivially copyable"). Which is
certainly *not* something any `expected` class should require. It's one
thing to use optimizations where available. It's quite another to enforce
arbitrary restrictions so that `expected` always has that performance.

Also, why do you think that the compiler-generated copy/move constructor
for `T` would be slower than a "POD assignment", if `T` were trivially
copyable?


> (And the compiler ought to be able
> to optimize away the dtor of the old instance.) *And* you're asserting
> that RVO is not possible for that? (Why?)
>

You can elide the return of the `expected`. But you still have to get the
value out of the `expected` value. You can get it by reference, but that's
only viable if you're not going to store that data anywhere else. If you
are, then you need to copy/move it.

Consider the use of such a thing in the initialization of a class data
member.

class Stuff
{
  T t = Function().value();
};

If that were just `T t = Function()`, the copy from the return value could
be elided. However, since I have to go through `expected`, no elision is
possible.


> I can write an even better `expected<T, ErrorEnum>`... it's standard
> layout and trivially copyable with size sizeof(T) + sizeof(ErrorEnum).
>

Actually, you can't. `expected` needs some data to know whether it's T or
`ErrorEnum`. Otherwise, the user can't tell the difference between the
error state or T being valid. So it needs at least one bit more than the
sum of the two.

Not unless you anoint some specific value of `ErrorEnum` to be "not an
error". Whick makes `ErrorEnum` something of a misnomer.

Also... I don't see how making `expected` *larger* than both of its
constituent components is "better". Just because something is standard
layout and trivial (as much as `T` or `EnumError` allow) doesn't make it
"better".

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5544_1496538987.1432226143831
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-20 20:2=
2, Nicol Bolas wrote:
<br>&gt; On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wr=
ote:
<br>&gt;&gt; The cognative overhead of catching=20
<br>&gt;&gt; exceptions vs. just checking something like a std::expected is=
 high.
<br>&gt;=20
<br>&gt; ... how, exactly?
<br>
<br>&nbsp; auto result =3D parse(input);
<br>
<br>&nbsp; if (result)
<br>&nbsp; &nbsp; do_something(*result);
<br>
<br>&nbsp; do_something_else();
<br>
<br>&nbsp; if (result)
<br>&nbsp; &nbsp; do_something_again(*result);
<br>
<br>- vs -
<br>
<br>&nbsp; T result; // grr, can't use auto
<br>&nbsp; auto is_valid =3D false;
<br>
<br>&nbsp; try {
<br>&nbsp; &nbsp; result =3D parse(input);
<br>&nbsp; &nbsp; is_valid =3D true;
<br>&nbsp; }
<br>&nbsp; catch(/* what goes here? */) { /* don't care */ }
<br>
<br>&nbsp; if (is_valid)
<br>&nbsp; &nbsp; do_something(result);
<br>
<br>&nbsp; do_something_else();
<br>
<br>&nbsp; if (is_valid)
<br>&nbsp; &nbsp; do_something_again(*result);
<br></blockquote><div><br>Nobody writes exception handling code like that, =
for the simple and obvious reason that nobody would want to.<br><br>You'd d=
o this:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">try</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> result </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> parse</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">input</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; do_something</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">result</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; do_something_else</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> <br>&nbsp; do_something_again</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">result</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">cat=
ch</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(&lt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">insert except=
ion here</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; do_somethin=
g_else</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></=
code></div><br>Alternatively, you could simply move `do_something_else` out=
side of the condition, unless there's a reason why `do_something_else` abso=
lutely must come before do_something_again`. In which case, maybe "else" sh=
ouldn't be part of the name ;)<br><br>Also, what happens if you need to han=
dle different kind of errors? After all, `parse` might fail for multiple re=
asons. The input could fail to match. Or the input couldn't be read from th=
e stream (aka: a filesystem error). The latter requires that you terminate =
the parsing operation, which must be handled at a higher level than this me=
re function.<br><br>What does your code look like then? How do you locally =
handle the input-failure error, while still propagating the filesystem erro=
r to the code that can actually terminate the parse operation?<br>&nbsp;</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">
So... a simple if() vs. a try-catch that requires me to know what I am
<br>supposed to be catching and potentially messes up my scope and/or
<br>control flow.
</blockquote><div><br>Ignoring the inaccuracy of the latter clause, knowing=
 what you are supposed to catch is... well, par for the course. See the abo=
ve scenario, where the reason for the failure materially affects how the us=
er should react to it.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">&gt; You can't possibly talk about the performance of something witho=
ut cover=20
<br>&gt; the actual circumstances of the specific instance. It doesn't matt=
er if the=20
<br>&gt; cost of catching an exception was even 100x the cost of a failed=
=20
<br>&gt; `expected`... if the exception is only thrown one out of every 10,=
000=20
<br>&gt; executions.
<br>
<br>Yes, but what if failure is frequent? In file parsing, this might not b=
e
<br>unusual. For that matter, what if I'm parsing a file whose fields may o=
r
<br>may not be numbers, and the way I determine that is by trying to parse
<br>the field as a number and seeing if it succeeds?</blockquote><div><br>T=
hen that would be a matter of your parsing interface. Such a function might=
 be called "parse_possible_integer" or whatever. The function, by its contr=
act with the caller, recognizes the possibility that the text may not be pa=
rsable as an integer.<br><br>There's a conceptual difference between "conve=
rt this text to an integer" and "if this text is an integer, convert it". T=
hese are two different functions. <br><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;">This reminds me of something I saw recently (not sure if =
it was this
<br>group) about not spending resources on malicious actions... but that's
<br>exactly what exceptions do; turn the case of bad input into the most
<br>expensive code path.<br></blockquote><div><br>"Bad input" is not necess=
arily "malicious". Indeed, it rarely is.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;">&gt; Not to mention the fact that you pay the `expe=
cted` cost all the time.=20
<br>&gt; Every return value gets bigger. When you get the return value, you=
 have to=20
<br>&gt; copy/move it out of the `expected`; not unless you plan on storing=
 it. So=20
<br>&gt; you can forget about eliding return values when you use `expected`=
; you=20
<br>&gt; have to do a copy/move. Not unless you're going to use the value i=
n-situ.
<br>&gt;=20
<br>&gt; So I'd say that your statement requires some actual evidence.
<br>
<br>I'd say that for your statement also. I could easily write a highly
<br>optimized `expected&lt;T, exception_ptr&gt;` whose size is only sizeof(=
T) +
<br>sizeof(void*) and whose move ctor consists of a POD assignment of a T
<br>and a void*, and a clear of a void*.</blockquote><div><br>... so? That'=
s still more expensive than elision. Also, that wasn't the expense I was ta=
lking about. Also, I'm pretty sure `exception_ptr` needs more than just a p=
ointer.<br><br>Also, a "POD assignment of a T" requires that T be a POD (or=
 whatever you're talking about. I think you mean "trivially copyable"). Whi=
ch is certainly <i>not</i> something any `expected` class should require. I=
t's one thing to use optimizations where available. It's quite another to e=
nforce arbitrary restrictions so that `expected` always has that performanc=
e.<br><br>Also, why do you think that the compiler-generated copy/move cons=
tructor for `T` would be slower than a "POD assignment", if `T` were trivia=
lly copyable?<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(=
And the compiler ought to be able
<br>to optimize away the dtor of the old instance.) *And* you're asserting
<br>that RVO is not possible for that? (Why?)<br></blockquote><div><br>You =
can elide the return of the `expected`. But you still have to get the value=
 out of the `expected` value. You can get it by reference, but that's only =
viable if you're not going to store that data anywhere else. If you are, th=
en you need to copy/move it.<br><br>Consider the use of such a thing in the=
 initialization of a class data member.<br><br>class Stuff<br>{<br>&nbsp; T=
 t =3D Function().value();<br>};<br><br>If that were just `T t =3D Function=
()`, the copy from the return value could be elided. However, since I have =
to go through `expected`, no elision is possible.<br>&nbsp;</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">
I can write an even better `expected&lt;T, ErrorEnum&gt;`... it's standard
<br>layout and trivially copyable with size sizeof(T) + sizeof(ErrorEnum).<=
br></blockquote><div><br>Actually, you can't. `expected` needs some data to=
 know whether it's T or `ErrorEnum`. Otherwise, the user can't tell the dif=
ference between the error state or T being valid. So it needs at least one =
bit more than the sum of the two.<br><br>Not unless you anoint some specifi=
c value of `ErrorEnum` to be "not an error". Whick makes `ErrorEnum` someth=
ing of a misnomer.<br><br>Also... I don't see how making `expected` <i>larg=
er</i> than both of its constituent components is "better". Just because so=
mething is standard layout and trivial (as much as `T` or `EnumError` allow=
) doesn't make it "better".</div></div>

<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 />

------=_Part_5544_1496538987.1432226143831--
------=_Part_5543_2079725137.1432226143831--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 21 May 2015 09:44:32 -0700 (PDT)
Raw View
------=_Part_669_1873555172.1432226672533
Content-Type: multipart/alternative;
 boundary="----=_Part_670_289059843.1432226672533"

------=_Part_670_289059843.1432226672533
Content-Type: text/plain; charset=UTF-8



On Thursday, May 21, 2015 at 11:48:07 AM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-21 11:34, Matthew Fioravante wrote:
> > On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Woehlke wrote:
> >> On 2015-05-20 20:22, Nicol Bolas wrote:
> >>> On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
> >>>> The cognative overhead of catching
> >>>> exceptions vs. just checking something like a std::expected is high.
> >>>
> >>> ... how, exactly?
> >> [...]
> >>> You can't possibly talk about the performance of something without
> cover
> >>> the actual circumstances of the specific instance. It doesn't matter
> if
> >>> the cost of catching an exception was even 100x the cost of a
> >>> failed `expected`... if the exception is only thrown one out of
> >>> every 10,000 executions.
> >>
> >> Yes, but what if failure is frequent?
> >
> > It really depends on what you're trying to do.
> >
> > If failure is frequent and you need to handle each individual failure
> > differently then exceptions get in the way. Its much easier (and also
> > possibly more efficient) to check a return code with if() instead of
> > setting up separate try/catch blocks around each call. The specific
> error
> > handling for each situation is also localized to where the error occurs,
> > improving readability.
>
> I could point out that you can individually wrap each call in its own
> try/catch, but as I was trying to illustrate, that's likely to be
> detrimental to readability :-).
>
> Actually, you caught the point I missed in my previous mail, responding
> to Nicol's question about cognative load... an if() checking the result
> at the point where you obtain it is easy to follow. Having to dig down
> an unknown number of layers of control flow to find an enclosing
> try/catch is much, much harder. Especially when exceptions start making
> it further up the stack before being caught, possibly in many different
> and widely varying locations.
>

But that's what makes the cognitive load *easier* with exceptions. The
local function *does not have to care*. It doesn't have to have syntax that
says, "if I get a filesystem error, return it. If I get a parsing error,
handle it like this. If I get some other kind of error, handle it like
that."

The exceptions that need to be handled locally are handled locally. No
syntax needs to be expended to handle non-local errors.



>
> > The one case where I've seen exceptions really shine is when you have an
> > all or nothing situation where you want to try a bunch of steps and just
> > bail out completely the same way if any one of them fails. For example
> you
> > want to do a bunch of file IO routines, or parse a text file, or do a
> > series of system calls, etc..
>
> ...so just don't check if your std::expected is valid :-).
>
> This (not talking to you - Matthew F. - specifically any more) is why I
> don't understand why the exception-worshippers object so strongly to
> std::expected.


Well, no "exception-worshippers" are objecting to it; at least, not that I
can see. So I don't see what you're talking about.

What is being "objected to" are:

1) The notion that `expected` is a better error reporting syntax than
exceptions.

2) The corresponding idea (and arguments in support of the position) that
exceptions are bad, wrong, poorly-thought-out-, or otherwise a priori
harmful.

3) The idea that the standard should abandon exceptions as the default
means of error handling.

If you prefer exceptions, *you can have exceptions*,
> almost trivially. They just aren't *forced* on you.
>

Only not. Because if I'm linking against code that uses arbitrary error
handling system X, I now have to convert those error methods into
exceptions. That's the nice thing about having a standard way of conveying
errors; inter-operation is much easier.

Conversely, the burden of forcing exceptions on those of us that don't
> want exceptions is much heavier.
>

I don't care. The horse is out of the barn and has won the Kentucky Derby;
it's too late to close the barn door.

Exceptions are *standard*. Full Stop.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_670_289059843.1432226672533
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, May 21, 2015 at 11:48:07 AM UTC-4, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05=
-21 11:34, Matthew Fioravante wrote:
<br>&gt; On Thursday, May 21, 2015 at 10:54:14 AM UTC-4, Matthew Woehlke wr=
ote:
<br>&gt;&gt; On 2015-05-20 20:22, Nicol Bolas wrote:=20
<br>&gt;&gt;&gt; On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Wo=
ehlke wrote:=20
<br>&gt;&gt;&gt;&gt; The cognative overhead of catching=20
<br>&gt;&gt;&gt;&gt; exceptions vs. just checking something like a std::exp=
ected is high.=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; ... how, exactly?=20
<br>&gt;&gt; [...]
<br>&gt;&gt;&gt; You can't possibly talk about the performance of something=
 without cover=20
<br>&gt;&gt;&gt; the actual circumstances of the specific instance. It does=
n't matter if=20
<br>&gt;&gt;&gt; the cost of catching an exception was even 100x the cost o=
f a
<br>&gt;&gt;&gt; failed `expected`... if the exception is only thrown one o=
ut of
<br>&gt;&gt;&gt; every 10,000 executions.
<br>&gt;&gt;
<br>&gt;&gt; Yes, but what if failure is frequent?
<br>&gt;=20
<br>&gt; It really depends on what you're trying to do. &nbsp;
<br>&gt;=20
<br>&gt; If failure is frequent and you need to handle each individual fail=
ure=20
<br>&gt; differently then exceptions get in the way. Its much easier (and a=
lso=20
<br>&gt; possibly more efficient) to check a return code with if() instead =
of=20
<br>&gt; setting up separate try/catch blocks around each call. The specifi=
c error=20
<br>&gt; handling for each situation is also localized to where the error o=
ccurs,=20
<br>&gt; improving readability.
<br>
<br>I could point out that you can individually wrap each call in its own
<br>try/catch, but as I was trying to illustrate, that's likely to be
<br>detrimental to readability :-).
<br>
<br>Actually, you caught the point I missed in my previous mail, responding
<br>to Nicol's question about cognative load... an if() checking the result
<br>at the point where you obtain it is easy to follow. Having to dig down
<br>an unknown number of layers of control flow to find an enclosing
<br>try/catch is much, much harder. Especially when exceptions start making
<br>it further up the stack before being caught, possibly in many different
<br>and widely varying locations.
<br></blockquote><div><br>But that's what makes the cognitive load <i>easie=
r</i> with exceptions. The local function <i>does not have to care</i>. It =
doesn't have to have syntax that says, "if I get a filesystem error, return=
 it. If I get a parsing error, handle it like this. If I get some other kin=
d of error, handle it like that."<br><br>The exceptions that need to be han=
dled locally are handled locally. No syntax needs to be expended to handle =
non-local errors.<br><br>&nbsp;<br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">
<br>&gt; The one case where I've seen exceptions really shine is when you h=
ave an=20
<br>&gt; all or nothing situation where you want to try a bunch of steps an=
d just=20
<br>&gt; bail out completely the same way if any one of them fails. For exa=
mple you=20
<br>&gt; want to do a bunch of file IO routines, or parse a text file, or d=
o a=20
<br>&gt; series of system calls, etc..=20
<br>
<br>...so just don't check if your std::expected is valid :-).
<br>
<br>This (not talking to you - Matthew F. - specifically any more) is why I
<br>don't understand why the exception-worshippers object so strongly to
<br>std::expected.</blockquote><div><br>Well, no "exception-worshippers" ar=
e objecting to it; at least, not that I can see. So I don't see what you're=
 talking about.<br><br>What is being "objected to" are:<br><br>1) The notio=
n that `expected` is a better error reporting syntax than exceptions.<br><b=
r>2) The corresponding idea (and arguments in support of the position) that=
 exceptions are bad, wrong, poorly-thought-out-, or otherwise a priori harm=
ful.<br><br>3) The idea that the standard should abandon exceptions as the =
default means of error handling.<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"> If you prefer exceptions, *you can have exceptions*,
<br>almost trivially. They just aren't *forced* on you.<br></blockquote><di=
v><br>Only not. Because if I'm linking against code that uses arbitrary err=
or handling system X, I now have to convert those error methods into except=
ions. That's the nice thing about having a standard way of conveying errors=
; inter-operation is much easier.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">
Conversely, the burden of forcing exceptions on those of us that don't
<br>want exceptions is much heavier.<br></blockquote><div><br>I don't care.=
 The horse is out of the barn and has won the Kentucky Derby; it's too late=
 to close the barn door.<br><br>Exceptions are <i>standard</i>. Full Stop.<=
br></div></div>

<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 />

------=_Part_670_289059843.1432226672533--
------=_Part_669_1873555172.1432226672533--

.


Author: "'Jeffrey Yasskin' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 21 May 2015 10:39:19 -0700
Raw View
On Thu, May 21, 2015 at 9:44 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
> Exceptions are standard. Full Stop.

The question here is whether the standard should change to accommodate
a non-exception error reporting mechanism. Just repeating that the
standard currently does not include that other mechanism, doesn't help
with answering that question.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 13:39:29 -0400
Raw View
On 2015-05-21 12:35, Nicol Bolas wrote:
> Also, what happens if you need to handle different kind of errors?

....then you would inspect the error portion of the std::expected. Which
might be an enum. Which *you can switch() on*. Try that with std::exception.

> Or the input couldn't be read from the stream (aka: a filesystem
> error). The latter requires that you terminate the parsing operation, which
> must be handled at a higher level than this mere function.

In that case, you would return from the function. (Or go ahead and throw
an exception, but I am assuming an environment which forbids exceptions.)

> There's a conceptual difference between "convert this text to an integer"
> and "if this text is an integer, convert it". These are two different
> functions.

That feels like an artificial distinction. 'std::expected<T, ParseError>
parse(...)' is an excellent API for both cases.

> ... so? That's still more expensive than elision. Also, that wasn't the
> expense I was talking about. Also, I'm pretty sure `exception_ptr` needs
> more than just a pointer.

Pointer and reference count, and the exception object itself. The latter
can be intrusive, or an additional level of indirection may be used, so
as to incur no cost in the non-error case. (I'm optimizing for the
non-error case, since that's the one you are concerned about.)

> class Stuff
> {
>   T t = Function().value();
> };
>
> If that were just `T t = Function()`, the copy from the return value could
> be elided. However, since I have to go through `expected`, no elision is
> possible.

Assuming that std::expected is inline (and it's a template, so it is)
and implemented properly, I expect elision. If not I would consider it a
missed optimization.

> Actually, you can't. `expected` needs some data to know whether it's
> T or `ErrorEnum`. Not unless you anoint some specific value of
> `ErrorEnum` to be "not an error". Whick makes `ErrorEnum` something
> of a misnomer.

I would do exactly that (probably 0, but I would accept 'tricks' like
having a constexpr template that the user can specialize to provide the
special value), and I don't see it as a misnomer at all. In existing
practice, it is common for 0 to indicate 'no error' and non-zero values
to indicate various possible errors.

IMO, the optimization advantage is well worth requiring that for
std::expected<T, EnumType>, a value of EnumType must indicate "no error".

Alternatively, it might be irrelevant. Note that I'm not claiming this
is the BEST implementation. Just that it is a POSSIBLE implementation
which disproves your assertion that std::expected 'can't possibly be
efficient'. Other possible implementations may be equally efficient
without the requirement of a special "no error" value.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 21 May 2015 20:52:43 +0300
Raw View
On 21 May 2015 at 20:39, 'Jeffrey Yasskin' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:
> On Thu, May 21, 2015 at 9:44 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
>> Exceptions are standard. Full Stop.
>
> The question here is whether the standard should change to accommodate
> a non-exception error reporting mechanism. Just repeating that the
> standard currently does not include that other mechanism, doesn't help
> with answering that question.


Also, the standard already does include an alternative mechanism -
exception_ptr.
You can use it to convey exceptions not unlike expected would, without
actually throwing
an exception.

The discussion about whether exceptions should or should not be the
only way to report
errors, and what to do on platforms where exceptions are prohibitively
expensive, seem
to miss part of the point of what expected is for. Part of its
motivation is for cases where
throwing an exception in the middle of processing something is so
annoying that it will
uglify the code beyond sanity. Such cases include collecting results
from multiple sub-tasks
into a larger result set and conveying that result set to a client.
The sub-tasks should not
throw their exceptions into that collection step, they should wrap the
exceptions so that
the result set can be built and the user can decide when to handle the
exceptions in the result set.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "Francis (Grizzly) Smit" <grizzlysmit@gmail.com>
Date: Fri, 22 May 2015 04:21:01 +1000
Raw View

On 22/05/15 00:53, Matthew Woehlke wrote:
> On 2015-05-20 20:22, Nicol Bolas wrote:
>> On Wednesday, May 20, 2015 at 7:30:06 PM UTC-4, Matthew Woehlke wrote:
>>> The cognative overhead of catching
>>> exceptions vs. just checking something like a std::expected is high.
>> ... how, exactly?
>    auto result = parse(input);

How can this work the compiler cannot know what will be in the value
input a int along a double a long double etc
the

type result parse<type>(input)

idea made sense but this??
also it has the advantage of looking like a sort of cast which it is in
a way,
and then we can have have  variants like:

int base = 2;
string tail;

type result = parse<type, base>(input, &tail);

where tail gets the left overs from parsing the input and we can decided
if that's an error or just parse tail for some thing else.

>
>    if (result)
>      do_something(*result);
>
>    do_something_else();
>
>    if (result)
>      do_something_again(*result);
>
> - vs -
>
>    T result; // grr, can't use auto
>    auto is_valid = false;
>
>    try {
>      result = parse(input);
>      is_valid = true;
>    }
>    catch(/* what goes here? */) { /* don't care */ }
>
>    if (is_valid)
>      do_something(result);
>
>    do_something_else();
>
>    if (is_valid)
>      do_something_again(*result);
>
> So... a simple if() vs. a try-catch that requires me to know what I am
> supposed to be catching and potentially messes up my scope and/or
> control flow.
>
>> You can't possibly talk about the performance of something without cover
>> the actual circumstances of the specific instance. It doesn't matter if the
>> cost of catching an exception was even 100x the cost of a failed
>> `expected`... if the exception is only thrown one out of every 10,000
>> executions.
> Yes, but what if failure is frequent? In file parsing, this might not be
> unusual. For that matter, what if I'm parsing a file whose fields may or
> may not be numbers, and the way I determine that is by trying to parse
> the field as a number and seeing if it succeeds? (I can certainly
> imagine this being more efficient than parsing the field twice, once to
> see if it "looks like" a number, then again to get the value... hoping
> on the second pass that I didn't miss something.)
>
> This reminds me of something I saw recently (not sure if it was this
> group) about not spending resources on malicious actions... but that's
> exactly what exceptions do; turn the case of bad input into the most
> expensive code path.
>
>> Not to mention the fact that you pay the `expected` cost all the time.
>> Every return value gets bigger. When you get the return value, you have to
>> copy/move it out of the `expected`; not unless you plan on storing it. So
>> you can forget about eliding return values when you use `expected`; you
>> have to do a copy/move. Not unless you're going to use the value in-situ.
>>
>> So I'd say that your statement requires some actual evidence.
> I'd say that for your statement also. I could easily write a highly
> optimized `expected<T, exception_ptr>` whose size is only sizeof(T) +
> sizeof(void*) and whose move ctor consists of a POD assignment of a T
> and a void*, and a clear of a void*. (And the compiler ought to be able
> to optimize away the dtor of the old instance.) *And* you're asserting
> that RVO is not possible for that? (Why?)
>
> I can write an even better `expected<T, ErrorEnum>`... it's standard
> layout and trivially copyable with size sizeof(T) + sizeof(ErrorEnum).
>

--

    .~.     In my life God comes first....
    /V\         but Linux is pretty high after that :-D
   /( )\    Francis (Grizzly) Smit
   ^^-^^    http://www.smit.id.au/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GM/CS/H/P/S/IT/L d- s+:+ a++ C++++ UL++++$ P++ L+++$ E--- W++
N W--- M-- V-- PE- PGP t+ 5-- X-- R- tv b++++ D-
G e++ h+ y?
------END GEEK CODE BLOCK------
http://www.geekcode.com/

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 14:49:20 -0400
Raw View
On 2015-05-21 14:21, Francis (Grizzly) Smit wrote:
>>    auto result = parse(input);
>
> How can this work the compiler cannot know what will be in the value
> input a int along a double a long double etc

You're reading too much into the example :-). It's meant to be
illustrative (more like pseudo-code), not compilable.

(And we're off topic; this thread is about std::expected :-).)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 15:03:37 -0400
Raw View
On 2015-05-21 12:44, Nicol Bolas wrote:
> On Thursday, May 21, 2015 at 11:48:07 AM UTC-4, Matthew Woehlke wrote:
>> Actually, you caught the point I missed in my previous mail, responding
>> to Nicol's question about cognative load... an if() checking the result
>> at the point where you obtain it is easy to follow. Having to dig down
>> an unknown number of layers of control flow to find an enclosing
>> try/catch is much, much harder. Especially when exceptions start making
>> it further up the stack before being caught, possibly in many different
>> and widely varying locations.
>
> But that's what makes the cognitive load *easier* with exceptions.

For you, maybe. For me, the potential for code flow to be interrupted at
some arbitrary point and restart at some other point, which is not only
also arbitrary but depends on the state of the call stack, is worse than
being able to follow the control flow directly.

> What is being "objected to" are:
>
> 1) The notion that `expected` is a better error reporting syntax than
> exceptions.

It is, by definition. Exceptions are unacceptable (to some people and/or
in some situations). Thus, *any* functional error reporting mechanism is
better.

> 2) The corresponding idea (and arguments in support of the position) that
> exceptions are bad, wrong, poorly-thought-out-, or otherwise a priori
> harmful.

I understand that you take issue with people that... ah, take issue with
exceptions. However, IMHO the burden is on you to convince us why we are
wrong. I don't see you trying to gently educate us as to why exceptions
are okay.

Until you can convince everyone that currently will not use exceptions
that exceptions are the best thing since classes (*and*, having done
that, also overcome the inertia of decades of code that is not exception
aware), the reality is that we need something else. The goal of
std::expected is to provide a good compromise that satisfies both camps
with minimal overhead.

If you find std::expected intolerable, for whatever reason, please try
constructively to either address its issues, propose an alternative that
is acceptable to both parties, or address the underlying issues that
folks have with exceptions.

> 3) The idea that the standard should abandon exceptions as the default
> means of error handling.

I don't think anyone is proposing to deprecate exceptions where they are
currently used. What we're objecting to is trying to force new and
otherwise desperately needed API on us that *is not usable without
exceptions*. (Which, per the current staus quo, means "not usable, period".)

>> If you prefer exceptions, *you can have exceptions*,
>> almost trivially. They just aren't *forced* on you.
>
> Only not. Because if I'm linking against code that uses arbitrary error
> handling system X, I now have to convert those error methods into
> exceptions. That's the nice thing about having a standard way of conveying
> errors; inter-operation is much easier.

That's a straw man. The current status quo has nothing to do with
whether or not std::expected would help... and in fact, the current
status quo is exactly why we *need* std::expected!

Right now we have a wild west of ways to report errors. std::expected
would give us an obvious standard way to do it where exceptions are not
acceptable, *and* it makes it trivial to promote errors to exceptions;
just pretend that errors never happen.

Try looking at it this way. Lots of people refuse to use exceptions, and
are going to continue to do so. Some of these people are going to write
libraries that are interesting to people that would prefer to use
exceptions. Now, which would you prefer?

  int result; // output parameter
  alib_do_something(&result, input);
  if (auto const e = alib_get_error)
    wrap_error_as_exception(e); // will throw

....or...

  // return is std::expected; value() will throw on error
  auto result = alib_do_something(input).value();

....?

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 21 May 2015 15:09:03 -0400
Raw View
On 2015-05-21 13:52, Ville Voutilainen wrote:
> The discussion about whether exceptions should or should not be the
> only way to report errors, and what to do on platforms where
> exceptions are prohibitively expensive, seem to miss part of the
> point of what expected is for. Part of its motivation is for cases
> where throwing an exception in the middle of processing something is
> so annoying that it will uglify the code beyond sanity.

Thanks; that's well taken.

Another example would be when I just don't care about errors, i.e. where
it is acceptable to use a default/fallback value if parsing fails. This
is stupid easy with std::expected (value_or()). Without, it may require
writing my own wrapper to catch exceptions and instead return a default
value.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 May 2015 16:52:09 -0400
Raw View
--089e011825869aba4705169db7b6
Content-Type: text/plain; charset=UTF-8

On Wed, May 20, 2015 at 4:52 PM, 'Matt Calabrese' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

>
> "expected", or discriminated unions in general, provide many benefits, and
> some drawbacks, over exceptions:
>
> ==========
>
> Feel free to correct anything that is wrong in the above assessment or to
> add to it. I am not an expert in this domain and these are just my personal
> thoughts.
>

That's a pretty good pro/con list.


>
> Not that the following has any chance of changing the language, but my
> personal thoughts have been that C++ exceptions are good, but would ideally
> be much more like a discriminated union in terms of implementation. By that
> I mean they still would not affect the return type of the function, as is
> already the case with current exceptions though not with "expected", but
> they would deal with a closed set of types rather than an open set. You
> would be able to query at compile time the set of possible exceptions and
> append to that set when making higher level functions (important for
> generic code -- this is also analogous to using noexcept to determine if an
> expression can throw or not). You'd always be able to effectively make an
> open set of exception types by using some kind of a polymorphic type (I.E.
> a type-erased object with a large small-object optimization), though you
> would lose some of the functionality of C++ exceptions as they are in the
> language. Exception propagation would continue to work as-is, as would
> accessing of the normal result of a function. Constructors would also work
> as easily as they do right now.
>
> This would basically just be C++ exceptions, only implemented on top of a
> discriminated union instead of an open set of types.
>
>
There are problems with a closed set of exceptions, which have been felt
with C++ throw(a,b,c) clauses and java checked exceptions, etc.
In particular, I can't call pointer-to-functions or virtual functions, etc,
because I can't know the set of possible exceptions.

Sure I could use polymorphic exceptions then, but I suspect we'd end up
using them almost everywhere, leaving us where we are now.

Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e011825869aba4705169db7b6
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, May 20, 2015 at 4:52 PM, &#39;Matt Calabrese&#39; via ISO C++ S=
tandard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-prop=
osals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span>=
 wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gm=
ail_extra"><br><div class=3D"gmail_quote"><span class=3D""></span><div>&quo=
t;expected&quot;, or discriminated unions in general, provide many benefits=
, and some drawbacks, over exceptions:</div><div><br></div><div>=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D</div><br><div>Feel free to correct anything that is w=
rong in the above assessment or to add to it. I am not an expert in this do=
main and these are just my personal thoughts.</div></div></div></div></bloc=
kquote><div><br></div><div>That&#39;s a pretty good pro/con list.<br>=C2=A0=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gma=
il_extra"><div class=3D"gmail_quote"><div><br></div><div>Not that the follo=
wing has any chance of changing the language, but my personal thoughts have=
 been that C++ exceptions are good, but would ideally be much more like a d=
iscriminated union in terms of implementation. By that I mean they still wo=
uld not affect the return type of the function, as is already the case with=
 current exceptions though not with &quot;expected&quot;, but they would de=
al with a closed set of types rather than an open set. You would be able to=
 query at compile time the set of possible exceptions and append to that se=
t when making higher level functions (important for generic code -- this is=
 also analogous to using noexcept to determine if an expression can throw o=
r not). You&#39;d always be able to effectively make an open set of excepti=
on types by using some kind of a polymorphic type (I.E. a type-erased objec=
t with a large small-object optimization), though you would lose some of th=
e functionality of C++ exceptions as they are in the language. Exception pr=
opagation would continue to work as-is, as would accessing of the normal re=
sult of a function. Constructors would also work as easily as they do right=
 now.</div><div><br></div><div>This would basically just be C++ exceptions,=
 only implemented on top of a discriminated union instead of an open set of=
 types.</div><br></div></div></div></blockquote></div><br></div><div class=
=3D"gmail_extra">There are problems with a closed set of exceptions, which =
have been felt with C++ throw(a,b,c) clauses and java checked exceptions, e=
tc.<br></div><div class=3D"gmail_extra">In particular, I can&#39;t call poi=
nter-to-functions or virtual functions, etc, because I can&#39;t know the s=
et of possible exceptions.<br><br></div><div class=3D"gmail_extra">Sure I c=
ould use polymorphic exceptions then, but I suspect we&#39;d end up using t=
hem almost everywhere, leaving us where we are now.<br><br></div><div class=
=3D"gmail_extra">Tony<br><br></div></div>

<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 />

--089e011825869aba4705169db7b6--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 May 2015 14:11:37 -0700
Raw View
On Thursday 21 May 2015 16:52:09 Tony V E wrote:
> There are problems with a closed set of exceptions, which have been felt
> with C++ throw(a,b,c) clauses and java checked exceptions, etc.
> In particular, I can't call pointer-to-functions or virtual functions, etc,
> because I can't know the set of possible exceptions.

Which is a good thing. You need to know what the function you're calling can
throw, regardless of whether you're doing a direct call, indirect or virtual.

The reimplementation of the function cannot suddenly start throwing unexpected
errors. The catch handler may not know how to handle those. New exception
types need to be caught and handled at a lower level, never leak.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 May 2015 17:21:58 -0400
Raw View
--001a113463a44485a205169e2256
Content-Type: text/plain; charset=UTF-8

On Thu, May 21, 2015 at 5:11 PM, Thiago Macieira <thiago@macieira.org>
wrote:

> On Thursday 21 May 2015 16:52:09 Tony V E wrote:
> > There are problems with a closed set of exceptions, which have been felt
> > with C++ throw(a,b,c) clauses and java checked exceptions, etc.
> > In particular, I can't call pointer-to-functions or virtual functions,
> etc,
> > because I can't know the set of possible exceptions.
>
> Which is a good thing. You need to know what the function you're calling
> can
> throw, regardless of whether you're doing a direct call, indirect or
> virtual.
>
> The reimplementation of the function cannot suddenly start throwing
> unexpected
> errors. The catch handler may not know how to handle those. New exception
> types need to be caught and handled at a lower level, never leak.
> --
>

So why are java developers moving away from checked exceptions, and C++ has
deprecated throws clauses?
Lack of Discipline?



> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a113463a44485a205169e2256
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, May 21, 2015 at 5:11 PM, Thiago Macieira <span dir=3D"ltr">&lt;=
<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.or=
g</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">=
On Thursday 21 May 2015 16:52:09 Tony V E wrote:<br>
&gt; There are problems with a closed set of exceptions, which have been fe=
lt<br>
&gt; with C++ throw(a,b,c) clauses and java checked exceptions, etc.<br>
&gt; In particular, I can&#39;t call pointer-to-functions or virtual functi=
ons, etc,<br>
&gt; because I can&#39;t know the set of possible exceptions.<br>
<br>
</span>Which is a good thing. You need to know what the function you&#39;re=
 calling can<br>
throw, regardless of whether you&#39;re doing a direct call, indirect or vi=
rtual.<br>
<br>
The reimplementation of the function cannot suddenly start throwing unexpec=
ted<br>
errors. The catch handler may not know how to handle those. New exception<b=
r>
types need to be caught and handled at a lower level, never leak.<br>
<span class=3D"im HOEnZb">--<br></span></blockquote><div><br></div><div>So =
why are java developers moving away from checked exceptions, and C++ has de=
precated throws clauses?<br></div><div>Lack of Discipline?<br><br></div><di=
v>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"im HOEnZb">
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=3D"_b=
lank">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C=C2=A0 966C 33F5 F005 6EF4 535=
8<br>
<br>
</span><div class=3D"HOEnZb"><div class=3D"h5">--<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<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 />

--001a113463a44485a205169e2256--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 21 May 2015 14:31:51 -0700
Raw View
--001a1130d45e9b4fd405169e4591
Content-Type: text/plain; charset=UTF-8

On Thu, May 21, 2015 at 1:52 PM, Tony V E <tvaneerd@gmail.com> wrote:
>
> There are problems with a closed set of exceptions, which have been felt
> with C++ throw(a,b,c) clauses and java checked exceptions, etc.
> In particular, I can't call pointer-to-functions or virtual functions,
> etc, because I can't know the set of possible exceptions.
>
> Sure I could use polymorphic exceptions then, but I suspect we'd end up
> using them almost everywhere, leaving us where we are now.
>

Hey, Tony!

I don't want to derail too far because I don't think it's realistic that
the language would change in this respect anyway, but what are the exact
pointer-to-function or virtual function concerns? My thoughts on this are
that the exception specification should probably affect the function type,
similar to what is now being proposed for noexcept, IIUC. In other words, a
function pointer would be able to be a pointer to a function that is
noexcept. Or, expanded, a pointer to a function that can possibly throw a
particular set of exceptions, also allowing it to bind to something that is
a subset of the possible exceptions. Similar constraints would apply to
overriding of virtual functions. I don't think that everyone would use
polymorphic exceptions everywhere since, in true C++ fashion, we would
probably have a way to refer to the list of exception types that an
exception could through (similar to using noexcept), and append to that
list, allowing even generic code to accumulate a finite set of exception
types. Some of this could even then be made automatic in certain
situations, similar to the often talked about idea of noexcept(auto). The
amount of places where exceptions truly need to be an open set of types, I
think, is much less than one might initially expect.

I know that Java has something a bit more similar to this, as you
mentioned, but I don't have enough experience in Java to comment on it. I
also understand that they are frequently despised, but it's not clear to me
that the criticisms are inherent to there being a closed set or simply a
matter of poor implementation.

My personal perspective is that I've worked in a world with exceptions,
I've worked in a world with expected-like types, and I've worked in a world
with a combination of the two. At the very least, in the situations that
I've been in personally (anecdotal, I know), I see no reason why everything
couldn't have been done with "expected" (and thus, a bounded set of failure
kinds) other than that it would have been more verbose using expected than
with exceptions, and would have made dealing with generic code considerably
more difficult. A closed set of types for exceptions could have effectively
provided many of the same benefits of an expected-like type without any of
the implementation concerns that come from an open set of exception types.

There are other benefits of a closed set of exception types. Once you have
a truly closed set that is known at compile-time, catching of exceptions
can then be done with as much power as something like visitation of a
discriminated union. By that I mean, since the possible types are known
statically and a catch would effectively now be akin to a
boost::apply_visitor, you can use the same kind of pattern matching that
you use when writing a function template. Quick example:

//////////
template<HRESULT Code>
struct hresult_exception { /**/ };

try { some_windows_function(); }
catch(hresult_exception<AParitcularCode>) { /**/ }
template<HRESULT Code> catch(hresult_exception<Code>) { /**/ }
//////////

Handling groups of exception kinds no longer needs to to rely on those
types being related by inheritance, thereby avoiding hierarchies, diamond
patterns, and a possible need for virtual inheritance. The actual
implementation of exception handling also becomes much simpler now and
doesn't require any sophisticated RTTI other than an integer discriminator
that is specific to the function that can throw the exception. It also
eliminates many of the concerns that people have when exceptions are
enabled in their compiler.

I've had this discussion with enough people to realize that I'm in a clear
minority here, but I've never been truly satisfied with counter arguments.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a1130d45e9b4fd405169e4591
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 21, 2015 at 1:52 PM, Tony V E <span dir=3D"ltr">&lt;<a href=3D"mail=
to:tvaneerd@gmail.com" target=3D"_blank">tvaneerd@gmail.com</a>&gt;</span> =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_e=
xtra">There are problems with a closed set of exceptions, which have been f=
elt with C++ throw(a,b,c) clauses and java checked exceptions, etc.<br></di=
v><div class=3D"gmail_extra">In particular, I can&#39;t call pointer-to-fun=
ctions or virtual functions, etc, because I can&#39;t know the set of possi=
ble exceptions.<br><br></div><div class=3D"gmail_extra">Sure I could use po=
lymorphic exceptions then, but I suspect we&#39;d end up using them almost =
everywhere, leaving us where we are now.</div></div></blockquote><div><br><=
/div><div>Hey, Tony!=C2=A0</div><div><br></div><div>I don&#39;t want to der=
ail too far because I don&#39;t think it&#39;s realistic that the language =
would change in this respect anyway, but what are the exact pointer-to-func=
tion or virtual function concerns? My thoughts on this are that the excepti=
on specification should probably affect the function type, similar to what =
is now being proposed for noexcept, IIUC. In other words, a function pointe=
r would be able to be a pointer to a function that is noexcept. Or, expande=
d, a pointer to a function that can possibly throw a particular set of exce=
ptions, also allowing it to bind to something that is a subset of the possi=
ble exceptions. Similar constraints would apply to overriding of virtual fu=
nctions. I don&#39;t think that everyone would use polymorphic exceptions e=
verywhere since, in true C++ fashion, we would probably have a way to refer=
 to the list of exception types that an exception could through (similar to=
 using noexcept), and append to that list, allowing even generic code to ac=
cumulate a finite set of exception types. Some of this could even then be m=
ade automatic in certain situations, similar to the often talked about idea=
 of noexcept(auto). The amount of places where exceptions truly need to be =
an open set of types, I think, is much less than one might initially expect=
..</div><div><br></div><div>I know that Java has something a bit more simila=
r to this, as you mentioned, but I don&#39;t have enough experience in Java=
 to comment on it. I also understand that they are frequently despised, but=
 it&#39;s not clear to me that the criticisms are inherent to there being a=
 closed set or simply a matter of poor implementation.</div><div><br></div>=
<div>My personal perspective is that I&#39;ve worked in a world with except=
ions, I&#39;ve worked in a world with expected-like types, and I&#39;ve wor=
ked in a world with a combination of the two. At the very least, in the sit=
uations that I&#39;ve been in personally (anecdotal, I know), I see no reas=
on why everything couldn&#39;t have been done with &quot;expected&quot; (an=
d thus, a bounded set of failure kinds) other than that it would have been =
more verbose using expected than with exceptions, and would have made deali=
ng with generic code considerably more difficult. A closed set of types for=
 exceptions could have effectively provided many of the same benefits of an=
 expected-like type without any of the implementation concerns that come fr=
om an open set of exception types.</div><div><br></div><div>There are other=
 benefits of a closed set of exception types. Once you have a truly closed =
set that is known at compile-time, catching of exceptions can then be done =
with as much power as something like visitation of a discriminated union. B=
y that I mean, since the possible types are known statically and a catch wo=
uld effectively now be akin to a boost::apply_visitor, you can use the same=
 kind of pattern matching that you use when writing a function template. Qu=
ick example:</div><div><br></div><div>//////////</div><div>template&lt;HRES=
ULT Code&gt;</div><div>struct hresult_exception { /**/ };</div><div><br></d=
iv><div>try { some_windows_function(); }</div><div>catch(hresult_exception&=
lt;AParitcularCode&gt;) { /**/ }</div><div>template&lt;HRESULT Code&gt; cat=
ch(hresult_exception&lt;Code&gt;) { /**/ }</div><div>//////////</div><div><=
br></div><div>Handling groups of exception kinds no longer needs to to rely=
 on those types being related by inheritance, thereby avoiding hierarchies,=
 diamond patterns, and a possible need for virtual inheritance. The actual =
implementation of exception handling also becomes much simpler now and does=
n&#39;t require any sophisticated RTTI other than an integer discriminator =
that is specific to the function that can throw the exception. It also elim=
inates many of the concerns that people have when exceptions are enabled in=
 their compiler.</div><div><br></div><div>I&#39;ve had this discussion with=
 enough people to realize that I&#39;m in a clear minority here, but I&#39;=
ve never been truly satisfied with counter arguments.</div></div></div></di=
v>

<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 />

--001a1130d45e9b4fd405169e4591--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 21 May 2015 14:33:28 -0700
Raw View
--90e6ba6e846058ae3805169e4beb
Content-Type: text/plain; charset=UTF-8

On Thu, May 21, 2015 at 2:31 PM, Matt Calabrese <calabrese@google.com>
wrote:

> I don't think that everyone would use polymorphic exceptions everywhere
> since, in true C++ fashion, we would probably have a way to refer to the
> list of exception types that an exception could through
>

Woops, mean to say "we would probably have a way to refer to the list of
exception types that an expression could throw"

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--90e6ba6e846058ae3805169e4beb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 21, 2015 at 2:31 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bor=
der-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail=
_extra"><div class=3D"gmail_quote"><div>I don&#39;t think that everyone wou=
ld use polymorphic exceptions everywhere since, in true C++ fashion, we wou=
ld probably have a way to refer to the list of exception types that an exce=
ption could through</div></div></div></div></blockquote><div><br></div><div=
>Woops, mean to say &quot;we would probably have a way to refer to the list=
 of exception types that an expression could throw&quot;</div></div></div><=
/div>

<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 />

--90e6ba6e846058ae3805169e4beb--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 21 May 2015 15:38:41 -0700
Raw View
--20cf303f64d0a15fd605169f3496
Content-Type: text/plain; charset=UTF-8

On Thu, May 21, 2015 at 2:21 PM, Tony V E <tvaneerd@gmail.com> wrote:
>
> On Thu, May 21, 2015 at 5:11 PM, Thiago Macieira <thiago@macieira.org>
> wrote:
>
>> On Thursday 21 May 2015 16:52:09 Tony V E wrote:
>> > There are problems with a closed set of exceptions, which have been felt
>> > with C++ throw(a,b,c) clauses and java checked exceptions, etc.
>> > In particular, I can't call pointer-to-functions or virtual functions,
>> etc,
>> > because I can't know the set of possible exceptions.
>>
>> Which is a good thing. You need to know what the function you're calling
>> can
>> throw, regardless of whether you're doing a direct call, indirect or
>> virtual.
>>
>> The reimplementation of the function cannot suddenly start throwing
>> unexpected
>> errors. The catch handler may not know how to handle those. New exception
>> types need to be caught and handled at a lower level, never leak.
>
> So why are java developers moving away from checked exceptions, and C++
> has deprecated throws clauses?
> Lack of Discipline?
>

At least on the C++ side of things, old-style dynamic exception
specifications are not really the same as having a fixed set of
compile-time-introspectible exception types.

I do personally believe that while dealing with a fixed compile-time set is
not always trivial, particularly without automatic deduction of such
compile-time specifications, it has actual benefits that aren't always
acknowledged. In ideal world, I think it is the approach that people should
generally prefer, but again, I know that I'm in the minority here.

Perhaps the most intriguing aspect of this from a practical perspective is
that much of the rationale for turning off exceptions, which is remarkably
common in the real world, would go away. It's sort of embarrassing that
there is a feature (really two features) in the language that many users
simply turn off, despite now making their implementation nonstandard, and
they often do so for actual legitimate reasons. I'm a fan of exceptions in
general, but IMO this is a symptom of flaws in how exceptions operate in
C++ and shouldn't be too quickly ignored.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--20cf303f64d0a15fd605169f3496
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, May 21, 2015 at 2:21 PM, Tony V E <span dir=3D"ltr">&lt;<a href=3D"mail=
to:tvaneerd@gmail.com" target=3D"_blank">tvaneerd@gmail.com</a>&gt;</span> =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_e=
xtra"><div class=3D"gmail_quote"><span class=3D"">On Thu, May 21, 2015 at 5=
:11 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=3D"mailto:thiago@maci=
eira.org" target=3D"_blank">thiago@macieira.org</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><span>On Thursday 21 May 2015 16:52:09 Tony V =
E wrote:<br>
&gt; There are problems with a closed set of exceptions, which have been fe=
lt<br>
&gt; with C++ throw(a,b,c) clauses and java checked exceptions, etc.<br>
&gt; In particular, I can&#39;t call pointer-to-functions or virtual functi=
ons, etc,<br>
&gt; because I can&#39;t know the set of possible exceptions.<br>
<br>
</span>Which is a good thing. You need to know what the function you&#39;re=
 calling can<br>
throw, regardless of whether you&#39;re doing a direct call, indirect or vi=
rtual.<br>
<br>
The reimplementation of the function cannot suddenly start throwing unexpec=
ted<br>
errors. The catch handler may not know how to handle those. New exception<b=
r>
types need to be caught and handled at a lower level, never leak.</blockquo=
te></span><div>So why are java developers moving away from checked exceptio=
ns, and C++ has deprecated throws clauses?<br></div><div>Lack of Discipline=
?</div></div></div></div></blockquote><div><br></div><div>At least on the C=
++ side of things, old-style dynamic exception specifications are not reall=
y the same as having a fixed set of compile-time-introspectible exception t=
ypes.</div><div><br></div><div>I do personally believe that while dealing w=
ith a fixed compile-time set is not always trivial, particularly without au=
tomatic deduction of such compile-time specifications, it has actual benefi=
ts that aren&#39;t always acknowledged. In ideal world, I think it is the a=
pproach that people should generally prefer, but again, I know that I&#39;m=
 in the minority here.</div><div><br></div><div>Perhaps the most intriguing=
 aspect of this from a practical perspective is that much of the rationale =
for turning off exceptions, which is remarkably common in the real world, w=
ould go away. It&#39;s sort of embarrassing that there is a feature (really=
 two features) in the language that many users simply turn off, despite now=
 making their implementation nonstandard, and they often do so for actual l=
egitimate reasons. I&#39;m a fan of exceptions in general, but IMO this is =
a symptom of flaws in how exceptions operate in C++ and shouldn&#39;t be to=
o quickly ignored.</div></div></div></div>

<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 />

--20cf303f64d0a15fd605169f3496--

.


Author: Patrice Roy <patricer@gmail.com>
Date: Thu, 21 May 2015 19:36:05 -0400
Raw View
--089e0160b6f0e71f7a0516a0010f
Content-Type: text/plain; charset=UTF-8

If I may: exceptions are necessary (there are cases that are not solved
without them) but do not need to be ubiquitous. Parsing errors are not
exceptional, as far as I know, and are probably not a good case for
exceptions-by-default. Exceptions are probably a good voluntarily-opting-in
in this case, just not the default.

We've had quite a lot of feedback, some informed and some less, on the
inappropriateness of exceptions in some cases. It's worth looking into. I
think this issue is takin way too much space and time in the current
thread, although it does deserve looking into in a different thread (SG14?)
since there is resistance to the exception mechanisms in domains where C++
is the language of choice.

Cheers!

2015-05-21 15:09 GMT-04:00 Matthew Woehlke <mw_triad@users.sourceforge.net>:

> On 2015-05-21 13:52, Ville Voutilainen wrote:
> > The discussion about whether exceptions should or should not be the
> > only way to report errors, and what to do on platforms where
> > exceptions are prohibitively expensive, seem to miss part of the
> > point of what expected is for. Part of its motivation is for cases
> > where throwing an exception in the middle of processing something is
> > so annoying that it will uglify the code beyond sanity.
>
> Thanks; that's well taken.
>
> Another example would be when I just don't care about errors, i.e. where
> it is acceptable to use a default/fallback value if parsing fails. This
> is stupid easy with std::expected (value_or()). Without, it may require
> writing my own wrapper to catch exceptions and instead return a default
> value.
>
> --
> Matthew
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e0160b6f0e71f7a0516a0010f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>If I may: exceptions are necessary (there are ca=
ses that are not solved without them) but do not need to be ubiquitous. Par=
sing errors are not exceptional, as far as I know, and are probably not a g=
ood case for exceptions-by-default. Exceptions are probably a good voluntar=
ily-opting-in in this case, just not the default.<br><br></div>We&#39;ve ha=
d quite a lot of feedback, some informed and some less, on the inappropriat=
eness of exceptions in some cases. It&#39;s worth looking into. I think thi=
s issue is takin way too much space and time in the current thread, althoug=
h it does deserve looking into in a different thread (SG14?) since there is=
 resistance to the exception mechanisms in domains where C++ is the languag=
e of choice.<br><br></div>Cheers!<br></div><div class=3D"gmail_extra"><br><=
div class=3D"gmail_quote">2015-05-21 15:09 GMT-04:00 Matthew Woehlke <span =
dir=3D"ltr">&lt;<a href=3D"mailto:mw_triad@users.sourceforge.net" target=3D=
"_blank">mw_triad@users.sourceforge.net</a>&gt;</span>:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><span class=3D"">On 2015-05-21 13:52, Ville Voutilainen wrot=
e:<br>
&gt; The discussion about whether exceptions should or should not be the<br=
>
&gt; only way to report errors, and what to do on platforms where<br>
&gt; exceptions are prohibitively expensive, seem to miss part of the<br>
&gt; point of what expected is for. Part of its motivation is for cases<br>
&gt; where throwing an exception in the middle of processing something is<b=
r>
&gt; so annoying that it will uglify the code beyond sanity.<br>
<br>
</span>Thanks; that&#39;s well taken.<br>
<br>
Another example would be when I just don&#39;t care about errors, i.e. wher=
e<br>
it is acceptable to use a default/fallback value if parsing fails. This<br>
is stupid easy with std::expected (value_or()). Without, it may require<br>
writing my own wrapper to catch exceptions and instead return a default<br>
value.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
Matthew<br>
</font></span><div class=3D"HOEnZb"><div class=3D"h5"><br>
--<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<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 />

--089e0160b6f0e71f7a0516a0010f--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 May 2015 17:53:17 -0700
Raw View
On Thursday 21 May 2015 17:21:58 Tony V E wrote:
> On Thu, May 21, 2015 at 5:11 PM, Thiago Macieira <thiago@macieira.org>
>=20
> wrote:
> > On Thursday 21 May 2015 16:52:09 Tony V E wrote:
> > > There are problems with a closed set of exceptions, which have been f=
elt
> > > with C++ throw(a,b,c) clauses and java checked exceptions, etc.
> > > In particular, I can't call pointer-to-functions or virtual functions=
,
> >=20
> > etc,
> >=20
> > > because I can't know the set of possible exceptions.
> >=20
> > Which is a good thing. You need to know what the function you're callin=
g
> > can
> > throw, regardless of whether you're doing a direct call, indirect or
> > virtual.
> >=20
> > The reimplementation of the function cannot suddenly start throwing
> > unexpected
> > errors. The catch handler may not know how to handle those. New excepti=
on
> > types need to be caught and handled at a lower level, never leak.
> > --
>=20
> So why are java developers moving away from checked exceptions, and C++ h=
as
> deprecated throws clauses?
> Lack of Discipline?

On the C++ side, because our implementation was never good. As you said, th=
e=20
exception specification was not carried in function pointers and there was =
no=20
provision for variance or contra-variance of exception specifications in=20
overriding of virtual functions.

What the correct thing should be, I'll have to defer to people who actually=
=20
use exceptions and have studied this problem.

My na=C3=AFve interpretation of the problem is that a function parse_number=
 that=20
used to throw a restricted set of exceptions shouldn't suddenly start throw=
ing=20
database_disconnected_exception. What is the caller of parse_number to do w=
hen=20
receiving such an exception that wasn't in the API contract? Let it leak an=
d=20
thus punt the problem to the higher level?  The best case scenario here is=
=20
that the application gets to std::terminate. Because it would be a worse=20
scenario if the application handled it wrongly.

try {
 auto port =3D parse_number<unsigned short>(str);
 database.connect(hostname, port);
 do_work(database);
} catch (number_out_of_range) {
 show("port number out of range");
} catch (database_disconnected_exception &e) {
 restart_database(hostname);
}

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: mats.taraldsvik@gmail.com
Date: Fri, 22 May 2015 03:14:04 -0700 (PDT)
Raw View
------=_Part_839_4566800.1432289644233
Content-Type: multipart/alternative;
 boundary="----=_Part_840_1592279955.1432289644234"

------=_Part_840_1592279955.1432289644234
Content-Type: text/plain; charset=UTF-8



On Thursday, 21 May 2015 23:33:30 UTC+2, Matt Calabrese wrote:
>
> On Thu, May 21, 2015 at 2:31 PM, Matt Calabrese <cala...@google.com
> <javascript:>> wrote:
>
>> I don't think that everyone would use polymorphic exceptions everywhere
>> since, in true C++ fashion, we would probably have a way to refer to the
>> list of exception types that an exception could through
>>
>
> Woops, mean to say "we would probably have a way to refer to the list of
> exception types that an expression could throw"
>

 FYI, Daniel Gutson is apparently working on implementing something not
entirely different from this,  (link to Daniel Gutson's post in the
Embedded C++ mailing list)
<http://www.open-std.org/pipermail/embedded/2015-April/000420.html>.

"exact match": catching a base class type of the thrown type does
> not success. IOW, no hierarchy traversing
> takes place on each catch() construct. This requires minimum (static)
> typeinfo data and O(1) matching algorithm.
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_840_1592279955.1432289644234
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, 21 May 2015 23:33:30 UTC+2, Matt Cala=
brese  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div><div class=3D"gmail_quote">On Thu, May 21, 2015 at 2:31 PM, Matt Calab=
rese <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-ob=
fuscated-mailto=3D"cYz3Y2lDunEJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';return =
true;">cala...@google.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-le=
ft-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div di=
r=3D"ltr"><div><div class=3D"gmail_quote"><div>I don't think that everyone =
would use polymorphic exceptions everywhere since, in true C++ fashion, we =
would probably have a way to refer to the list of exception types that an e=
xception could through</div></div></div></div></blockquote><div><br></div><=
div>Woops, mean to say "we would probably have a way to refer to the list o=
f exception types that an expression could throw"</div></div></div></div></=
blockquote><div><br>&nbsp;FYI, Daniel Gutson is apparently working on imple=
menting something not entirely different from this,&nbsp; <a href=3D"http:/=
/www.open-std.org/pipermail/embedded/2015-April/000420.html">(link to Danie=
l Gutson's post in the Embedded C++ mailing list)</a>.<br><br><blockquote s=
tyle=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204=
); padding-left: 1ex;" class=3D"gmail_quote"><pre>"exact match": catching a=
 base class type of the thrown type does
not success. IOW, no hierarchy traversing
takes place on each catch() construct. This requires minimum (static)
typeinfo data and O(1) matching algorithm.</pre></blockquote><br><br></div>=
</div>

<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 />

------=_Part_840_1592279955.1432289644234--
------=_Part_839_4566800.1432289644233--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 22 May 2015 08:36:36 -0700 (PDT)
Raw View
------=_Part_531_1076904764.1432308996372
Content-Type: multipart/alternative;
 boundary="----=_Part_532_546191632.1432308996372"

------=_Part_532_546191632.1432308996372
Content-Type: text/plain; charset=UTF-8

Has there been any language that already implemented this style of static
closed set exceptions? It does sound like it could make the exception
problem much more tractable but I'm sure it has other pitfalls we won't
know about until we start trying to develop applications with it.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_532_546191632.1432308996372
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Has there been any language that already implemented this =
style of static closed set exceptions? It does sound like it could make the=
 exception problem much more tractable but I'm sure it has other pitfalls w=
e won't know about until we start trying to develop applications with it.</=
div>

<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 />

------=_Part_532_546191632.1432308996372--
------=_Part_531_1076904764.1432308996372--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 May 2015 10:07:22 -0700 (PDT)
Raw View
------=_Part_2223_1359874136.1432400842698
Content-Type: multipart/alternative;
 boundary="----=_Part_2224_1883632378.1432400842698"

------=_Part_2224_1883632378.1432400842698
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba=
=20
wrote:
>
>  Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
> =20
> On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:=20
>>
>> On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas <jmck...@gmail.com> wrote:=
=20
>> > I just want to see the "sto*" functions get string_view ASAP. We=20
>> shouldn't=20
>> > wait on `expected` just to accomplish that.=20
>>
>> That seems like a straightforward paper to get through the committee.=20
>> If you write it, I'll try to prevent the group from creeping its=20
>> scope.=20
>>
>
> Actually, that paper already exists (N4015=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>),=20
> with a revision (N4109=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>).=20
> According to Vicente Escriba, who both wrote those proposals and replied=
=20
> here, scope creep has already started. Also, N4109 has been a while ago=
=20
> (almost a year now), with no followup paper from any discussions based on=
=20
> it.
>
>   Yes its me. There is an error on the web page that I have already=20
> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt nam=
e=20
> and Botet Escriba is my last name.=20
>
> The expected proposal was blocked as the expected proposal was proposing=
=20
> an alternative way to report errors and the standard C++ has already one:=
=20
> exceptions. A study of all the alternative ways to reporting errors was=
=20
> requested so we can take a decision on which ones could be used once the=
=20
> advantages and liabilities of each approach are detailed. I'm not a paper=
=20
> writer and writing such a paper needs to be done carefully and it would=
=20
> takes time. If there are any volunteers to write it, please do it, it wil=
l=20
> be a pleasure to help. Of course, I will be very happy is this paper=20
> unblocks the expected proposal.
>

To help support this, I have written the attached rough draft document. It=
=20
attempts to be a survey of as many error reporting mechanisms as possible.=
=20
This document is *attempting* to be purely factual, with as little bias as=
=20
possible. As such, it doesn't have a "pros/cons" list, as what might be a=
=20
"pro" for one application is a "con" for another. It tries to be=20
descriptive of each method, along several use cases, without stumping for=
=20
or arguing against any particular one.

Note that the document is fairly lengthy, as there are quite a few ways to=
=20
go about reporting errors to users, and there are a lot of consequences for=
=20
difference schemes of error handling and resolution.

As this is a very rough draft, I'm interested in commentary in the=20
following areas:

* What error reporting mechanisms have I missed?

* I examine all of the error mechanisms in the context of 3 broad=20
use-cases: 1) what you do to resolve errors locally, 2) what you do to=20
resolve errors non-locally even across threads, 3) what you do to ignore an=
=20
error entirely, with a discussion of how you might find places where you've=
=20
ignored an error by accident. What other dimensions/use cases could be=20
useful for analyzing them?

* When examining one of the error mechanisms, have I missed some important=
=20
way that it interacts with one of the use cases?

* General mistakes/misconceptions/gross biases/rampaging stupidities at=20
work.

--=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/.

------=_Part_2224_1883632378.1432400842698
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J=
.. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>Le 19/05/15 03:01, Nicol Bolas a
      =C3=A9crit&nbsp;:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM UTC-4,
        Jeffrey Yasskin wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">On Mon,
          May 18, 2015 at 2:57 PM, Nicol Bolas &lt;<a rel=3D"nofollow">jmck=
....@gmail.com</a>&gt;

          wrote: <br>
          &gt; I just want to see the "sto*" functions get string_view
          ASAP. We shouldn't <br>
          &gt; wait on `expected` just to accomplish that. <br>
          <br>
          That seems like a straightforward paper to get through the
          committee. <br>
          If you write it, I'll try to prevent the group from creeping
          its <br>
          scope. <br>
        </blockquote>
        <div><br>
          Actually, that paper already exists (<a href=3D"http://www.open-s=
td.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf" target=3D"_blank" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A=
%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4015.=
pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';return=
 true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2F=
www.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4015.pdf\46=
sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';return true;=
">N4015</a>),

          with a revision (<a href=3D"http://www.open-std.org/JTC1/SC22/WG2=
1/docs/papers/2014/n4109.pdf" target=3D"_blank" rel=3D"nofollow" onmousedow=
n=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.o=
rg%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa\75D\46sntz\=
0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2FJ=
TC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;">N4109</a>).


          According to Vicente Escriba, who both wrote those proposals
          and replied here, scope creep has already started. Also, N4109
          has been a while ago (almost a year now), with no followup
          paper from any discussions based on it.<br>
          <br>
        </div>
      </div>
    </blockquote>
    Yes its me. There is an error on the web page that I have already
    reported. My name is Vicente J. Botet Escriba. Vicente J. is my
    fisrt name and Botet Escriba is my last name. <br>
    <br>
    The expected proposal was blocked as the expected proposal was
    proposing an alternative way to report errors and the standard C++
    has already one: exceptions. A study of all the alternative ways to
    reporting errors was requested so we can take a decision on which
    ones could be used once the advantages and liabilities of each
    approach are detailed. I'm not a paper writer and writing such a
    paper needs to be done carefully and it would takes time. If there
    are any volunteers to write it, please do it, it will be a pleasure
    to help. Of course, I will be very happy is this paper unblocks the
    expected proposal.<br></div></blockquote><div><br></div>To help support=
 this, I have written the attached rough draft document. It attempts to be =
a survey of as many error reporting mechanisms as possible. This document i=
s <i>attempting</i> to be purely factual, with as little bias as possible. =
As such, it doesn't have a "pros/cons" list, as what might be a "pro" for o=
ne application is a "con" for another. It tries to be descriptive of each m=
ethod, along several use cases, without stumping for or arguing against any=
 particular one.<br><br>Note that the document is fairly lengthy, as there =
are quite a few ways to go about reporting errors to users, and there are a=
 lot of consequences for difference schemes of error handling and resolutio=
n.<br><br>As this is a very rough draft, I'm interested in commentary in th=
e following areas:<br><br>* What error reporting mechanisms have I missed?<=
br><br>* I examine all of the error mechanisms in the context of 3 broad us=
e-cases: 1) what you do to resolve errors locally, 2) what you do to resolv=
e errors non-locally even across threads, 3) what you do to ignore an error=
 entirely, with a discussion of how you might find places where you've igno=
red an error by accident. What other dimensions/use cases could be useful f=
or analyzing them?<br><br>* When examining one of the error mechanisms, hav=
e I missed some important way that it interacts with one of the use cases?<=
br><br>* General mistakes/misconceptions/gross biases/rampaging stupidities=
 at work.<br></div>

<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 />

------=_Part_2224_1883632378.1432400842698--
------=_Part_2223_1359874136.1432400842698
Content-Type: text/html; charset=US-ASCII;
 name="Survey of Error Handling.html"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="Survey of Error Handling.html"
X-Attachment-Id: f51021de-b7a6-4b44-94cc-c3361076b1c9
Content-ID: <f51021de-b7a6-4b44-94cc-c3361076b1c9>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
</head>
<body>
<div id="TOC">
<ul>
<li><a href="#purpose-of-errors">Purpose of errors</a></li>
<li><a href="#terminology-and-organization">Terminology and organization</a></li>
<li><a href="#survey-of-error-methods">Survey of error methods</a><ul>
<li><a href="#error_code_return_value">Error code as return value</a></li>
<li><a href="#error_code_out_param">Error code as output parameter</a></li>
<li><a href="#special_return_value">Special return value</a></li>
<li><a href="#out_of_band">Out-of-band error codes</a></li>
<li><a href="#exceptions">Exceptions</a></li>
<li><a href="#return_variant">Variant as a return value</a></li>
</ul></li>
</ul>
</div>
<p>All functions have some purpose for which they are designed; each function is meant to do some particular thing. But functions can sometimes fail to do that, whether through faulty parameters, violations of pre-conditions, or even program-external state which has failed to achieve anything.</p>
<p>Error handling is a very important issue for most C++ programs. When a function is incapable of performing the action that has been requested of it, then the function which invoked that process needs to be informed of this failure. If a function does not report errors, then the function is assumed to be incapable of failing to do what it is intended to do</p>
<p>This paper will attempt to catalog the various ways that errors are handled across the wide variety in the C++ ecosystem. This paper will focus on errors that the user can at least theoretically recover from, rather than those for which termination (with possibly some data sent to an error dump) is the only possible response.</p>
<p>This paper is intended to be a catalog of information about the various error reporting mechanisms. It is not intended to judge one mechanism as being better than any other. It is intended merely to present the facts of how they work under various conditions, so that informed decisions can be made about them.</p>
<h1 id="purpose-of-errors">Purpose of errors</h1>
<p>The question of what it means for a function to issue an error is somewhat ambiguous. It is easy to get programmers to agree on some kinds of error conditions. The failure to open a file is an error condition, for example. But other kinds of conditions are more murky. Is failure to parse an error?</p>
<p>For the purpose of this paper, we will assume that an error is a condition that has halted the progress of some function. That function has decided that it cannot carry out, in part or in full, the operation that its caller gave to it. Therefore, it must do two things: transfer control to some other code, and inform the other code that an error occurred.</p>
<p>Some APIs provide a strong error guarantee: if the function reports an error, then it is as if the function were never called. Other APIs do not, leaving the system in a partial or uncertain state.</p>
<p>This question is entirely orthogonal to the matter of how the error is actually handled. As this paper is focused on error handling, rather than the state of the system after generation, this paper will ignore what kind of error guarantees the prospective systems offer. This paper focuses on how the information about the error is conveyed to the user.</p>
<h1 id="terminology-and-organization">Terminology and organization</h1>
<p>When talking about errors, it is very important to know which code we are talking about at any particular time. Therefore, the following terminology will be used:</p>
<ul>
<li><em>user</em>: The client code which intends to call one or more functions.</li>
<li><em>API</em>: The collection of functions and interfaces that the <em>user</em> is calling into.</li>
<li><em><code>TargetFunc</code></em>: A function that is part of the <em>API</em>, which needs to report whether it has succeeded or failed, as well as provide information about the failure.</li>
<li><em><code>CallerFunc</code></em>: This is the specific function that is directly calling <code>TargetFunc</code>. It is part of the user's code.</li>
<li><em>error code</em>: The term refers to some object, generated by <code>TargetFunc</code>, which is used by the <em>user</em> to determine information about the nature of the error generated. This is not necessarily a value of type <code>std::error_code</code>. It could be a number, an enumerator, or a user-defined object type (by value, pointer, reference or what-have-you). Thus, the values thrown by exceptions are considered to be &quot;error codes&quot;.</li>
<li><em>error handling</em>: To handle an error, for the purposes of this document, means to perform some form of conditional logic based on that error. This is purely at the syntactic level; the code will do one thing in the presence of an error, and another thing in the absence of an error.</li>
<li><em>error resolution</em>: To resolve an error is a stronger process than merely handling it. To resolve an error means to get to a point in the code where processing can proceed as though the error did not happen. Error resolution can involve many different error handling steps, sometimes in entirely separate scopes. Error resolution is about the semantics of the program.</li>
</ul>
<p>Each of the following error reporting mechanisms will feature an explanation of the concept, followed by a detailed look at the specific consequences of the mechanism. In particular, each mechanism will be examined under the following circumstances:</p>
<ul>
<li><p>Local error resolution: When <code>TargetFunc</code> errors, what exactly must <code>CallerFunc</code> do if it wishes to resolve the error locally, such that external code need not be aware that the error took place?</p>
<p>Local error resolution is a common scenario. Many kinds of errors are expected to be fielded and handled by the direct caller of a particular <code>TargetFunc</code>.</p></li>
<li><p>Non-local error resolution: When <code>TargetFunc</code> errors, what must <code>CallerFunc</code> do in order to communicate that error condition to other code, so that it can be resolved by this other code?</p>
<p>This will also involve a discussion of propagating errors across thread boundaries, so that the failure of a thread or similar process can be effectively communicated.</p>
<p>Non-local error resolution is important for any error mechanism. The ability to pass errors through functions makes layering and wrapping APIs effective. It is also important because the particular <code>CallerFunc</code> may not be at the correct level to actually resolve the error.</p></li>
<li><p>Ignored errors: If <code>TargetFunc</code> fails, can <code>CallerFunc</code> simply ignore that failure without testing for it? If complete ignorance is not possible, how much effort must be spent in order for <code>CallerFunc</code> to proceed as though the error did not take place? If an error is ignored, and the program terminates or encounters some other hard failure state because of it, is there a &quot;paper trail&quot; leading back to <code>CallerFunc</code>'s invocation of <code>TargetFunc</code>?</p>
<p>This will also include a discussion of what it takes to detect and diagnose such ignored errors. Is it possible for compilers to be able to detect such ignored errors without too many false positives? Can off-line tools be written to scan code for such ignoring syntax?</p>
<p>For some uses of APIs, ignoring an error is a legitimate act. Sometimes, an algorithm does not care if the process completely correctly or not. At the same time, ignoring errors can also lead to an increasingly unstable system, leading to a difficult-to-track fault or malfunction. Either way, the concept is important to analyze.</p></li>
</ul>
<h1 id="survey-of-error-methods">Survey of error methods</h1>
<h2 id="error_code_return_value">Error code as return value</h2>
<p>This is one of the most common forms of error reporting. <code>TargetFunc</code>'s return value is designated an error code. <code>CallerFunc</code> can test this code to see if an error took place or not.</p>
<p>Many APIs, particularly C-based ones, use this as their primary means of error reporting.</p>
<h3 id="local-error-resolution">Local error resolution</h3>
<p>Locally resolving returned error code values is fairly simple, syntactically. The return value is tested with an <code>if</code> statement of some sort. A common way to do it is as follows:</p>
<pre><code>if(TargetFunc(...) != &lt;no error&gt;)
{
  //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>Of course, this syntax completely ignores the specific nature of <code>TargetFunc</code>'s error. For error reports where the resolution requires the error code itself, the code tends to be structured this way:</p>
<pre><code>if((auto error_value = TargetFunc(...)) != &lt;no error&gt;)
{
    //Failure code, testing error_value for the type of error.
}

//Success or state is otherwise fine.</code></pre>
<p>There is an additional syntactic burden beyond the above. Since C++ can only return a single value from a function, the error code takes the place of whatever <code>TargetFunc</code>'s return value would have been. For functions that do not conceptually return values, this is fine.</p>
<p>But this imposes a burden for those functions that would like to return a value, however. The value must become an output parameter. For functions that return simple types, this means that <code>CallerFunc</code> must do something like this:</p>
<pre><code>output_type output_value = {};
if((auto error_value = TargetFunc(output_value, ...)) != &lt;no error&gt;)
{
    //Failure code, testing error_value for the type of error.
}

//Success or state is otherwise fine.</code></pre>
<p>This makes the code look a bit awkward. It also prevents <code>auto</code> dediction of <code>TargetFunc</code>'s true output.</p>
<p>A more pressing problem is that <code>output_type</code> must be either default constructible or constructible in way that is directly exposed to the user. If the non-move/copy constructors of the class are private, and <code>TargetFunc</code> is creating the class instance for the user (and thus, the error code represents construction failure), then this poses a problem for the interface. In that case, <code>TargetFunc</code> will have to allocate the instance and &quot;return&quot; a pointer to the instance.</p>
<h3 id="non-local-error-resolution">Non-local error resolution</h3>
<p>Propagating the error code up the call stack imposes a significant syntactic burden. <code>CallerFunc</code> must now have some way of communicating the error itself, typically via the return value. And every function that could potentially propagate this error must also return it.</p>
<p>This becomes more complicated in the case of a function that calls a number of different functions, each of which might error with different error code types. This now requires that <code>CallerFunc</code> must return some form of variant type, with all of the possible error codes lists. Furthermore, any code between <code>CallerFunc</code> and the eventual consumer of the error must be aware of every possible error code type, even if they do not wish to consume that particular type.</p>
<p>Note that this is very much like the C++98/03 problem with <code>throw</code> specifications on function definitions. The use of <code>any</code> could be useful in hiding the type, but this forces significant burden on the eventual resolution code, which must attempt to <code>any_cast</code> it to every possible error code type that it can resolve.</p>
<p>Return values via <code>std::thread</code> are not permitted. However, returning values via <code>std::async</code> or <code>future</code>/<code>promise</code> are quite safe, void of race conditions. Return values of arbitrary types are supported by these mechanisms.</p>
<h3 id="ignored-errors">Ignored errors</h3>
<p>Handling returned error codes requires more effort than ignoring them. To ignore them, <code>CallerFunc</code> simply does nothing with the return value. This also means that it is very easy for <code>CallerFunc</code> to <em>accidentally</em> ignore the error.</p>
<p>Even when errors are ignored, there remains some minor burden. <code>CallerFunc</code> is ignoring the return value, but it cannot ignore the syntactic consequence of <code>TargetFunc</code>'s return value being an error code. This means that it is impossible for <code>CallerFunc</code> to chain calls in one statement, even if it is ignoring the error code. This is of course because the function's true output is a parameter, so it must be handled on a separate line:</p>
<pre><code>return_type output_value = {};
TargetFunc(output_value, ...);
output_value.OtherFunction();</code></pre>
<p>This also has the unfortunate burden of forcing <code>output_value</code> to exist until the termination of the current block. If it were a return value temporary, it could have been destroyed immediately after being used by <code>OtherFunction</code>.</p>
<p>While a simple textual search tool cannot detect where returned error codes are ignored, it is possible to write such a tool based on C++ compiler front-ends like Clang. Compilers, if they know that a particular type is an error code (perhaps via an attribute), can certainly generate warnings if a function does not at least use the value in an expression. This also would allow the user to specify, by convention, that an error is being ignored deliberately:</p>
<pre><code>TargetFunc(...); //Accidental error ignorance.
(TargetFunc(...)); //Used in a parenthesis expression, therefore intensional.</code></pre>
<p>If ignoring the error eventually leads to termination or malfunction due to incoherent internal state, there is generally no way to track the source of that error back to <code>CallerFunc</code>. In some cases, the crash may happen within <code>CallerFunc</code>, but in many cases, it will happen in a distant location.</p>
<h2 id="error_code_out_param">Error code as output parameter</h2>
<p>This is an alternative version of returning an error code value. Instead of using the function's return value, the error code is made into an output parameter. <code>CallerFunc</code> provides a non-const pointer/reference to an error code value, which <code>TargetFunc</code> will fill in.</p>
<p><a href="http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm">Boost.Filesystem</a>, and the current <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4099.html">FileSystem proposed TS</a> both use this method for many functions (as alternatives to <a href="#exceptions">exceptions</a>. These overloads are provided as an alternative to the versions of functions that take exceptions.</p>
<h3 id="local-error-resolution-1">Local error resolution</h3>
<p>The syntax is slightly more complex than for returned error codes, owing to two facts. First, the error code variable must be declared before it is used. And second, because the return value is not the error code, one cannot put <code>TargetFunc</code> directly into a conditional statement:</p>
<pre><code>error_code ec = {};
TargetFunc(..., ec);
if(ec != &lt;no error&gt;
{
    //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>Additional syntactic burdens are placed upon the code. If <code>TargetFunc</code> returns a value, it must always return a value, which must be a live C++ object. Therefore, in the event of an error, the returned object must be in some well-defined-yet-innocuous state. And therefore, any object returned by <code>TargetFunc</code> must support being in such a state.</p>
<pre><code>error_code ec = {};
auto output_value = TargetFunc(..., ec);
if(ec != &lt;no error&gt;)
{
    //Failure code.
    //If not returning, `output_value` may need fixup.
}

//Success or state is otherwise fine.</code></pre>
<p>The use of <code>optional</code>, from the current <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4480.html">library fundamentals v1 DTS</a>, can alleviate the requirements placed on <code>TargetFunc</code>'s return type. In the event of an error, <code>TargetFunc</code> can simply return <code>nullopt</code>.</p>
<p>Parameter error codes also put a syntactic burden on the error code type itself. It must be constructible by the user. The error code type used in the return value case could be a class who's non-move/copy constructors are all private. That could be done to ensure that only those functions who are authorized to construct them may do so. This cannot be used for parameter error codes.</p>
<h3 id="non-local-error-resolution-1">Non-local error resolution</h3>
<p>The issues for non-local resolution are, generally speaking, identical to those for returning error codes. <code>CallerFunc</code> must explicitly propagate the error code, either as a return value or an output parameter, to higher-level code.</p>
<p>Propagating by output parameter is a bit more difficult than by returning the error code directly. This is because a function may have to propagate multiple kinds of errors, which would have to go into some kind of variant type. So the variant would need to have some valid state before <code>CallerFunc</code> put the error code into it. While some variants do have an empty state, not all variant types permit this (at least, not without explicitly declaring one of the states to be empty).</p>
<p>Using output parameters in a thread function or other forms of async dispatch is highly dangerous, for several reasons. Pointers to error code objects have to be used, since it is a rare case of thread dispatch (at least with modern syntax; asyc/await may change this) where a reference to an automatic object can be easily used. Furthermore, access to the referenced memory needs to have some kind of synchronization to avoid data races.</p>
<h3 id="ignored-errors-1">Ignored errors</h3>
<p>Unlike returning error codes, <code>CallerFunc</code> must always provide at least some syntax to ignore an error. It must instantiate an error code object and pass a pointer/reference to <code>TargetFunc</code>:</p>
<pre><code>error_code ec = {};
auto output_value = TargetFunc(..., ec);</code></pre>
<p>However, <code>CallerFunc</code> only has to declare one error code for each of the kinds of error codes that the various target functions it calls use. So the syntactic cost, while not negligible, is fairly minimal.</p>
<p>Doing a textual search for the error code type is sufficient to at least find all of the places where functions that provide those errors are being used. This means a simple find-in-files is somewhat sufficient for finding such locations, though a compiler front-end based method will be more robust to aliasing, macros, and so forth.</p>
<p>Because at least some syntax is required to store the error, it is at least marginally more difficult to ignore it by accident.</p>
<p>With this syntax, it is possible to ignore the error while chaining. So this is legal code:</p>
<pre><code>error_code ec = {};
auto output_value2 = TargetFunc(..., ec).OtherFunction();</code></pre>
<p>It would even be legal to pass <code>ec</code> to <code>OtherFunction</code>. The specific error will be lost, but since <code>CallerFunc</code> is ignoring errors anyway, this is irrelevant.</p>
<p>The semantic consequences of ignoring an error reported in this way are equivalent to ignoring error codes returned by <code>TargetFunc</code>.</p>
<h2 id="special_return_value">Special return value</h2>
<p>Some data types have values which are considered to be non-legal values. IEEE-754 floating-point numbers have NaN values, which are literally &quot;Not a Number&quot;. Pointers can be null, which represents an unusable pointer value.</p>
<p>In some cases, return values could be technically legal for a particular type, but make no sense in a particular context. For example, if a function returns an index as an <code>int</code>, it could return a negative number. If indices are not allowed to be negative, this is a conceptually illegal value, while still legally being a valid <code>int</code>.</p>
<p>Functions can return such special values in lieu of explicit error codes. In most cases, these can only represent simple, binary error codes; either an error happened, or the value is legitimate. In some cases, there can be a range of error states. In the negative integer case, the particular negative number could specify the specific failure mode.</p>
<p>This kind of error reporting is used in some APIs that normally use other error reporting mechanisms. For example, OpenGL generally uses <a href="#out_of_band">out-of-band error codes</a>. But some OpenGL functions, like <a href="https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGetUniformLocation.xml">glGetUniformLocation</a>, will simply return an illegal value if the named uniform location does not exist in the program. No OpenGL error is generated in this way.</p>
<h3 id="local-error-resolution-2">Local error resolution</h3>
<p>While it is inviting to attempt to use the same structural syntax as the case of returning error codes, that is not possible here. Because the error code and return value are the same object, the return value will often need to be visible outside of the condition that resolve the error. As such, this case often looks like this:</p>
<pre><code>auto output_value = TargetFunc(...);

if(output_value == &lt;error&gt;)
{
    //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>The syntax is fairly minimal, comparable to the syntax for the prior cases.</p>
<h3 id="non-local-error-resolution-2">Non-local error resolution</h3>
<p>Because the error value and real return value are the same, propagating the error to other code is very natural. This natural propagation extends only to code that has some interest in <code>TargetFunc</code>'s return value. For code where no such interest exists, propagating an error becomes more difficult.</p>
<p>Because code that does not care about the actual value may need to have errors propagated to it, <code>CallerFunc</code> or a similar function in the sequence will have to translate the error state. This improves, to some degree, the issue of having only binary pass/fail error state for many kinds of special values. <code>CallerFunc</code> can translate the error into a proper error code type for consumption by others.</p>
<p>This method works well for most forms of asynchronous dispatch operations, as it relies only on returning values.</p>
<h3 id="ignored-errors-2">Ignored errors</h3>
<p>Because the error code and return value are the same, it is highly unlikely that the user will want to simply ignore the value. Thus, this section will consider &quot;ignoring the error&quot; to simply mean not checking to see if it is a valid value.</p>
<p>Syntax-wise, this results in code that looks normal:</p>
<pre><code>auto output_value = TargetFunc(...);
//Do something with `output_value`.</code></pre>
<p>Tracking such syntax statically is fairly difficult, as it requires knowing that a specific return value from a specific function needs to be error tested. And usually, such types are common types like pointers or integers, so it would be difficult for even a syntax-aware tool to automatically find such ignored values.</p>
<p>Semantically, ignoring such errors has potentially created another avenue for problems. Whatever <code>CallerFunc</code> does with the illegal value effectively corrupts any expression it is used in. This is the classic issue of storing a null pointer in a location where everyone expects the pointer to not be null. Other code will access it on the assumption that it is valid when it is not. Otherwise, other code will have to constantly check that it is valid even when it is.</p>
<p>This corruption can have far-ranging implications. Depending on where a variable is set from, it can also be exceedingly difficult to track down where the null pointer came from. Setting memory breakpoints and other debugging tools can help.</p>
<p>Even worse, the range of possible broken behavior is extremely wide. Null pointers tend to be the safest, as they usually crash the program immediately upon their use. Floating-point quiet NaN can be used in any math operation without causing a hard fault. Each expression corrupts everything around it, leading to corrupted state throughout the program. The error spreads without being seen or dealt with.</p>
<p>Some APIs can be robust against such corruption. For example, in the OpenGL function listed above (<code>glGetUniformLocation</code>), failure is purely silent. All API functions that take uniform locations will also take the <code>GL_INVALID_INDEX</code> error value. They will then ignore any calls that pass this index, pretending to do whatever they were asked without actually doing anything.</p>
<h2 id="out_of_band">Out-of-band error codes</h2>
<p>Though much less common for simple functions, this error scheme is often used on an library-wide level. Among the most well-known users of this scheme is the OpenGL API, but other APIs like <a href="http://cairographics.org/manual/">cairo</a> use it as well. The C++ iostreams library uses this means of reporting many kinds of errors (though it can also fire <a href="#out_of_band">exceptions</a>, if set up properly).</p>
<p>The general idea is that errors are not reported in any way by the failed function. Instead, user code is required to call a specific API, which returns an error code if a previous API function call failed.</p>
<p>Where the out-of-band error is stored depends on the API. In cairo and iostream, it is stored in and retrieved from a C or C++ object. In OpenGL, errors are stored in a more nebulous object called an &quot;OpenGL context&quot;.</p>
<h3 id="local-error-resolution-3">Local error resolution</h3>
<p>Local testing syntax does not directly impinge on <code>TargetFunc</code>'s API. <code>CallerFunc</code> does not need to do any special processing of return values or provide any special parameters. Thus, the code looks quite normal:</p>
<pre><code>auto output_value = TargetFunc(...);

if((auto ec = DidError()) != &lt;no error&gt;)
{
    //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>A common shorthand technique for dealing with errors, particularly in OpenGL, is to use a macro:</p>
<pre><code>glTargetFunc(...); CHECK_OPENGL_ERRORS();</code></pre>
<p>Where <code>CHECK_OPENGL_ERRORS</code> would be defined as this:</p>
<pre><code>#define CHECK_OPENGL_ERRORS()\
    while((GLenum ec = glGetError()) != GL_NO_ERROR) DoSomethingWithError(ec);</code></pre>
<p>The while loop is particular to OpenGL, as it can queue up multiple errors.</p>
<h3 id="non-local-error-resolution-3">Non-local error resolution</h3>
<p>This kind of error reporting system works well for non-local testing of errors. Once the error code is logged with the owning object, any code that has access to that object can later decide to respond to the error. Thus, the syntactic burden is essentially minimal. <code>CallerFunc</code> needs no special syntax to pass the error to any other code, save ensuring that access to the object that owns the error is provided. In most cases, <code>CallerFunc</code> was given a reference or pointer to the object, so its caller almost always has access to it.</p>
<p>A problem can be created if multiple API functions are called between checking the object's error state, as each individual function call may fail and emit an error. In OpenGL, errors are stored in a FIFO queue; <code>glGetError</code> must be called in a loop as shown above to empty the error queue. By contrast, cairo and iostream only store one error; cairo stores the most recent error, while iostream stores the first error.</p>
<p>When doing non-local testing, there is no syntactic connection between the testing site and the call to <code>TargetFunc</code> that generated the error, save the object that stores the error. It therefore can be difficult to track down the particular <code>CallerFunc</code> that generated the error. This is particularly so if the suite of possible error codes is small, and thus the number of <code>TargetFunc</code>s that could result in any particular code is large.</p>
<p>Communicating such errors across thread boundaries is only as difficult as communicating the object containing those errors across thread boundaries. However, non-local testing creates an additional problem for transmission across threads. Because errors are held in some object, it becomes possible to generate new errors while processing old ones on a different thread.</p>
<p>Different APIs deal with this in different ways.</p>
<p>OpenGL explicitly makes this impossible. In OpenGL, errors are part of the specific OpenGL context that generated them. And OpenGL functions can only be called when a context is &quot;current&quot;; any errors generated go into the current context. Each thread maintains a separate current context, and the context management API explicitly prevents the same context from being current in multiple threads at the same time. Thus, it is impossible to issue errors in one thread while reading them in another.</p>
<p>Cairo and iostream are less forceful. They simply declare that calls into the same object are unsynchronized and can thus cause data races on the error state.</p>
<h3 id="ignored-errors-3">Ignored errors</h3>
<p>The syntactic cost of ignoring errors is trivial. It requires nothing more than not checking the error code. This also means that it is virtually impossible to write a tool to detect places where errors are being ignored. The only way to do so is to go through the API's documentation and catalog all functions that can emit an error, then search the code for every use of those functions.</p>
<p>If an ignored error from one function begets multiple errors from later functions, then it becomes difficult to find the specific <code>TargetFunc</code> that caused it. Even if the error system stores the name of the function that emitted an error, one would still need to track down the specific <code>CallerFunc</code> that called it.</p>
<p>In the OpenGL world, this has led to the development of debugging tools, DLLs that slip between the application and OpenGL itself. These are used for function logging, but they can also record which error if any was generated by that function.</p>
<h3 id="callback-alternative">Callback alternative</h3>
<p>This is a rather uncommon version of out-of-band error reporting. In this scheme, the user can register a callback with the system that will be called whenever an error occurs.</p>
<p>The OpenGL API allows for it, but only in the more recent <a href="https://www.opengl.org/wiki/Debug_Output">Debug Output</a> feature. As the name suggests, this feature is only guaranteed to be available when creating debugging OpenGL contexts.</p>
<p>This scheme is mostly useful for logging errors and the like. As a means of actually resolving errors, it is more or less useless, as the callback has a very limited ability to affect control flow. Therefore, this scheme is only noted as a variation, not a full error reporting mechanism on its own.</p>
<h2 id="exceptions">Exceptions</h2>
<p>The exception mechanism is composed of two parts, both built into the C++ language. The first part is within <code>TargetFunc</code>. To signal an error with this mechanism, target function &quot;throws&quot; an arbitrary error code object. Error code objects, when using this mechanism, are called &quot;exceptions&quot;.</p>
<p>Throwing an exception operates like a <code>return</code> statement, from a local perspective. Using the <code>throw</code> statement terminates all progress in the current function and returns control to some function higher up in the call stack. Unlike an actual return statement, it does not necessarily return control to its immediate caller. And it certainly does not return control to the location where <code>TargetFunc</code> was called.</p>
<p>To handle an exception requires first bracketing the code that could possibly throw that exception in a <code>try</code> block. This block is followed by one or more <code>catch</code> blocks; each <code>catch</code> block states which specific exception type it handles. Thus, a single <code>try</code> block could catch multiple different exceptions, and resolve them each in a different way.</p>
<p>If code in a <code>try</code> block throws an exception, and one of that <code>try</code> block's <code>catch</code> statements matches the type of the exception that was thrown, then control transfers to that catch block. However, in order to maintain the sanity of the call stack, before control is transfered to the <code>catch</code> block, all automatic objects between the cite of the <code>throw</code> and the receiving <code>catch</code> block must be destroyed, in the reverse order that they were created. This process is called &quot;stack unwinding&quot;.</p>
<p>Once the stack has been unwound, control is transferred to the beginning of the <code>catch</code> block, which receives the exception object thrown. This object is the only information that the catch block has about the error besides the exception's type. Once control exits the catch block, the code proceeds as normal (skipping any other <code>catch</code> blocks associated with the <code>try</code> block).</p>
<p>If, for a particular call stack, no appropriate <code>catch</code> block can be found for a particular thrown exception, then <code>std::terminate</code> will be called, halting the application.</p>
<p>Exceptions are the only error mechanism for signaling constructor failure that is recognized by the C++ language itself. Either a constructor succeeds in initializing a valid object, or an exception is thrown. Out-of-band error methods could be used to detect a form of constructor failure. But this usually requires that the object be able to exist in a &quot;created but not valid&quot; state or some otherwise empty state. As far as C++ as a language is concerned, if the constructor did not throw, then the object is valid and it is legal to manipulate it in accord with C++'s rules.</p>
<h3 id="local-error-resolution-4">Local error resolution</h3>
<p>Locally resolving exceptions requires significant syntax:</p>
<pre><code>try
{
    TargetFunc(...);
}
catch(exception &amp;ec)
{
    //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>If the failure condition results in returning to the calling function, then the normal code on success can be folded into the <code>try</code> block:</p>
<pre><code>try
{
    TargetFunc(...);
    //Success
}
catch(exception &amp;ec)
{
    //Failure code, returning control to caller.
}</code></pre>
<p>This puts the error resolution code at the end, removing it from the flow of the main logic.</p>
<p>Exceptions are a separate communication pathway from function return values or parameters, so they interfere with neither.</p>
<h3 id="non-local-error-resolution-4">Non-local error resolution</h3>
<p>The syntactic burden for <code>CallerFunc</code> to pass the exception along is, on the surface, nil. Code can look perfectly normal, yet still allow exceptions to pass through it.</p>
<p>However, there are syntactic costs for any code through which exceptions can pass. Local code must structure all resource management as though stack unwinding could happen at any time. If resources are allocated, local code must be designed to ensure that they will be released in the event, not just of that function returning, but also if any function it calls throws an exception.</p>
<p>This need, among others, has given rise to the modern RAII-style of C++ resource management. Resources are bound by objects; resources are acquired in a constructor and are owned by that object. When the object is destroyed, the resource is released. This style of development lets the user ensure that resources will be released during stack unwinding.</p>
<p>Allowing exceptions to pass through resources that are not managed by RAII objects imposes either additional syntactic burden (creating a <code>catch(...)</code> block and freeing resources manually) or faces the risk of leaving resources dangling.</p>
<p>While <code>std::thread</code> itself does not propagate exceptions across threads, <code>std::future</code> and <code>std::promise</code> are capable of doing just that. Indeed, if a <code>promise</code> stores an exception, attempting to <code>get</code> that value from the <code>future</code> will automatically throw that exception. <code>std::async</code> automatically forwards exceptions through the same mechanism.</p>
<h3 id="ignored-errors-4">Ignored errors</h3>
<p>There are several levels of safety when it comes to ignoring the possibility of throwing exceptions in <code>CallerFunc</code>. In the lowest level of safety, the code is unsafe for the stack to be unwound through the function. This would be due to the aforementioned lack of RAII-bound resources.</p>
<p>A higher level of safety assumes that any exceptions that pass the function will be handled by someone else. It is safe to stack unwinding, but the code makes no effort to catch exceptions. The latter case requires either the use of RAII objects or using a number of <code>catch(...)</code> blocks to free resources.</p>
<p>Because ignoring exceptions requires no special syntax (in and of itself) it is difficult to statically track down locations where exceptions can pass through. It is still possible, though it would require substantial static analysis tools which have access to a program's full source code.</p>
<p>Uncaught exceptions will result in program termination. And in most debugging systems, such exceptions will point the debugger directly to the source of the exception. Thus, at runtime, it is relatively easy to see where an exception was ignored.</p>
<p>If an exception goes uncaught and terminates the program, this does ensure that the program is terminated due to the uncaught exception. This could be instead of allowing potential data corruption to take place due to continuing to execute the code in an erroneous or invalid state. It could also be instead of allowing the program to proceed ahead, if the exception could have ben safely ignored.</p>
<h2 id="return_variant">Variant as a return value</h2>
<p>This method is conceptually a combination of <a href="#error_code_return_value">returning an error code</a> and <a href="#special_return_value">returning a value that acts as its own error code</a>. The idea is to wrap the desired return type in a type-safe variant, a discriminated union container that knows the type it holds and will stop the user from trying to do the wrong thing with it. This allows functions with return types to return a value or signal an error, without fundamentally changing the return type.</p>
<p>There are two variations of this method, using two different types. The first uses <code>std::optional</code>, part of the <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4480.html">library fundamentals v1 DTS</a>. <code>optional</code> is essentially a variant that can either be empty or contain one type of value, supplied by the template parameter. As error code information is not encoded, <code>optional</code> can only say that an operation failed, not why it failed.</p>
<p>The other alternative is <code>expected</code>, which is a variant that cannot be empty, but it can be one of two types, both supplied by template parameters. The first is the expected type, the type that would be returned if the function executed as desired. The second is the error code value, which is returned if the function failed. <code>expected</code> was <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf">proposed in paper N4109.</a></p>
<p>This section will focus on the form of <code>expected</code> defined in the linked proposal, as it is capable of returning actual error code information.</p>
<h3 id="local-error-resolution-5">Local error resolution</h3>
<p>The syntactic burden for resolving errors locally is very similar to the returned error code method:</p>
<pre><code>auto exp_value = TargetFunc(...);
if(!exp_value)
{
    auto ec = exp_value.error()
    //Failure code, perhaps correcting state or returning.
}

//Success or state is otherwise fine.</code></pre>
<p>However, the user has options to avoid even that. The <code>value_or</code> member function can be used to use a default value if the original is not present:</p>
<pre><code>auto output_value = TargetFunc(...).value_or(default_value);
//Success</code></pre>
<p>This could be considered a form of ignoring the error, but it only applies a default value when an error has occurred. Since different behavior is happening based on the error, it is still effectively handling the error.</p>
<h3 id="non-local-error-resolution-5">Non-local error resolution</h3>
<p>Non-local testing can happen in one of two ways. The first way is the traditional method for return-value-based systems: returning the error. This would usually be by extracting and returning the error code itself:</p>
<pre><code>auto exp_value = TargetFunc(...);
if(!exp_value)
{
    auto ec = exp_value.error()
    return ec
}

//Success.
return {}; //Default constructs a non-error.</code></pre>
<p>However, depending on a user's needs, the entire <code>expected</code> object itself could be stored or returned. This would mean that any code that uses it would have to check the value. This is similar in many regards to the special return value method, where it is possible to store an illegal value that outlives <code>CallerFunc</code>. The difference is that <code>excepted</code> forces any code that tries to access it to actually test for the presence of an error.</p>
<p>An alternative way to handle non-local errors is to combine <code>expected</code> with exceptions:</p>
<pre><code>auto output_value = TargetFunc(...).value();
//Success</code></pre>
<p><code>expected::value</code> will throw an exception if the particular <code>expected</code> object contains an error value. The proposal currently throws its own exception type, wrapping the error value within it. However, if the error type is <code>std::exception_ptr</code>, it calls <code>std::rethrow_exception</code>, so as to do proper exception forwarding.</p>
<p><code>expected</code> values use value semantics. Therefore, pushing them across threads works to the same extent that any return value can work.</p>
<h3 id="ignored-errors-5">Ignored errors</h3>
<p>In most uses of <code>expected</code>, the value type is meaningful to the user. This makes it unlikely for the user to simply discard the return value. So it is impossible to completely ignore the fact that the return is wrapped in an <code>expected</code>. The <code>value_or</code> function makes it possible to minimize the impact, but if the user wants to get the potential value it stores, the user must try to get the value.</p>
<p>This means that it is possible to search for code that uses such constructs. The word &quot;value&quot; is sufficiently common that one would need to use a C++ compiler front-end based tool to do the search without generating too many false positives. It would be less likely for compilers to be willing to issue a warning for using <code>value</code>, as there are legitimate reasons to use it in various locations.</p>
<p><code>expected</code> can still work for functions which do not return values. Such functions would return the <code>expected&lt;void, error_code&gt;</code> template partial specialization class. However, in terms of ignoring errors, this is not much better than returning the error code itself.</p>
<p>There is one advantage to this construct, however. When it comes to finding places in code where the user has dropped an error, a C++-aware script could search for the use of any function that returns any kind of <code>expected</code> object, regardless of type. If the user discards the return value, then the user is ignoring an error, and therefore is probably doing something wrong. Compilers could even generate warnings based on ignoring <code>expected&lt;void&gt;</code> return values specifically.</p>
<h3 id="optional-vs-expected">optional vs expected</h3>
<p>These two types seem similar; they even share the <code>value_or</code> syntax. However, they are quite different semantically. A function which returns <code>optional&lt;T&gt;</code> is saying that it may or may not return a <code>T</code>. But this does not necessarily mean that the lack of a <code>T</code> means that an error happened.</p>
<p>Whereas if function returns an error-valued <code>expected</code> object, this means that some form of error has taken place. The two concepts are syntactically similar, yet semantically different. Thus, it is semantically reasonable to talk about an <code>expected&lt;optional&lt;T&gt;&gt; ec&gt;</code>. That represents a function where returning &quot;null&quot; is not an error, yet the function's processing is capable of erroring out.</p>
</body>
</html>

------=_Part_2223_1359874136.1432400842698--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Sat, 23 May 2015 20:16:43 +0200
Raw View
On 05/23/2015 07:07 PM, Nicol Bolas wrote:

> * What error reporting mechanisms have I missed?

Networking TS (N4478) passes the return value of asynchronous
operations as parameters in handlers (callbacks), something along the
lines of:

   void async_operation(input arguments, [](output arguments) {});

So when the operation returns an std::size_t, then the handler has this
signature:

   void handler(std::error_code, std::size_t);

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 May 2015 11:31:55 -0700 (PDT)
Raw View
------=_Part_2229_1567952603.1432405915320
Content-Type: multipart/alternative;
 boundary="----=_Part_2230_807566284.1432405915320"

------=_Part_2230_807566284.1432405915320
Content-Type: text/plain; charset=UTF-8

On Saturday, May 23, 2015 at 2:16:48 PM UTC-4, Bjorn Reese wrote:
>
> On 05/23/2015 07:07 PM, Nicol Bolas wrote:
>
> > * What error reporting mechanisms have I missed?
>
> Networking TS (N4478) passes the return value of asynchronous
> operations as parameters in handlers (callbacks), something along the
> lines of:
>
>    void async_operation(input arguments, [](output arguments) {});
>
> So when the operation returns an std::size_t, then the handler has this
> signature:
>
>    void handler(std::error_code, std::size_t);
>
>
It's funny. I had a section on a scheme somewhat like that (based on
OpenGL's). But I shortened to just an adendum to the out-of-band error
section. I decided that, since there was no way to actually resolve the
error (the code that issued the call that provoked the error wouldn't be
informed), it wasn't a viable option for people looking for a way to let
users resolve errors.

I hadn't really considered the utility of the concept as a way of resolving
errors within an operation that was fundamentally asynchronous. I'll take a
look at the networking proposal and add an appropriate section on this kind
of error reporting.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_2230_807566284.1432405915320
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, May 23, 2015 at 2:16:48 PM UTC-4, Bjorn Reese=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 05/23/2015 07:07 PM,=
 Nicol Bolas wrote:
<br>
<br>&gt; * What error reporting mechanisms have I missed?
<br>
<br>Networking TS (N4478) passes the return value of asynchronous
<br>operations as parameters in handlers (callbacks), something along the
<br>lines of:
<br>
<br>&nbsp; &nbsp;void async_operation(input arguments, [](output arguments)=
 {});
<br>
<br>So when the operation returns an std::size_t, then the handler has this
<br>signature:
<br>
<br>&nbsp; &nbsp;void handler(std::error_code, std::size_t);
<br>
<br></blockquote><div><br>It's funny. I had a section on a scheme somewhat =
like that (based on OpenGL's). But I shortened to just an adendum to the ou=
t-of-band error section. I decided that, since there was no way to actually=
 resolve the error (the code that issued the call that provoked the error w=
ouldn't be informed), it wasn't a viable option for people looking for a wa=
y to let users resolve errors.<br><br>I hadn't really considered the utilit=
y of the concept as a way of resolving errors within an operation that was =
fundamentally asynchronous. I'll take a look at the networking proposal and=
 add an appropriate section on this kind of error reporting.<br></div></div=
>

<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 />

------=_Part_2230_807566284.1432405915320--
------=_Part_2229_1567952603.1432405915320--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Sat, 23 May 2015 14:10:32 -0700 (PDT)
Raw View
------=_Part_366_1274902036.1432415432297
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

> What error reporting mechanisms have I missed?

You haven't mentioned errno; although I'm not sure it counts as a separate =
mechanism, it's odd not to see it mentioned. While it's largely an adjunct =
to "special return value", it can also function as an out of band error cod=
e:

> For some system calls and library functions (e.g., getpriority(2)),
>       -1 is a valid return on success.  In such cases, a successful retur=
n
>       can be distinguished from an error return by setting errno to zero
>       before the call, and then, if the call returns a status that
>       indicates that an error may have occurred, checking to see if errno
>       has a nonzero value.
- http://man7.org/linux/man-pages/man3/errno.3.html

Another important mechanism, though without support in modern languages, is=
 FORTRAN-style alternate return - passing in (an) alternative program locat=
ion(s) to return to. Dijkstra disliked it, of course, along with multiple e=
ntry, but with appropriate syntactic structure I think it could actually wo=
rk in C++. See http://programmers.stackexchange.com/a/118793

Also, how would you classify setjmp/longjmp? I'm fairly sure there are stil=
l some C libraries that use it as their preferred error handling technique.=
 Clearly it's similar to exceptions in that both are stack based non local =
return, but there's plenty of differences, unwinding being just one.=20

--=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/.

------=_Part_366_1274902036.1432415432297--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 May 2015 14:30:51 -0700 (PDT)
Raw View
------=_Part_584_117271920.1432416651527
Content-Type: multipart/alternative;
 boundary="----=_Part_585_1746655141.1432416651527"

------=_Part_585_1746655141.1432416651527
Content-Type: text/plain; charset=UTF-8



On Saturday, May 23, 2015 at 5:10:32 PM UTC-4, Edward Catmur wrote:
>
> > What error reporting mechanisms have I missed?
>
> You haven't mentioned errno; although I'm not sure it counts as a separate
> mechanism, it's odd not to see it mentioned. While it's largely an adjunct
> to "special return value", it can also function as an out of band error
> code:
>
> > For some system calls and library functions (e.g., getpriority(2)),
> >       -1 is a valid return on success.  In such cases, a successful
> return
> >       can be distinguished from an error return by setting errno to zero
> >       before the call, and then, if the call returns a status that
> >       indicates that an error may have occurred, checking to see if
> errno
> >       has a nonzero value.
> - http://man7.org/linux/man-pages/man3/errno.3.html
>
>
`errno` is purely an out-of-band error reporting scheme. However, you could
combine any out-of-band scheme with the special return values. The SRV
signals the error, and the out-of-band state explains its nature. I should
mention that when discussing SRVs.


> Another important mechanism, though without support in modern languages,
> is FORTRAN-style alternate return - passing in (an) alternative program
> location(s) to return to. Dijkstra disliked it, of course, along with
> multiple entry, but with appropriate syntactic structure I think it could
> actually work in C++. See http://programmers.stackexchange.com/a/118793
>

Since such a thing doesn't really work in C++ as it currently stands, I
don't think it's appropriate for discussion. I'm not trying to catalog
every possible mechanism for handling errors, only the ones that can be
used in C++.


> Also, how would you classify setjmp/longjmp? I'm fairly sure there are
> still some C libraries that use it as their preferred error handling
> technique. Clearly it's similar to exceptions in that both are stack based
> non local return, but there's plenty of differences, unwinding being just
> one


Since using longjmp in C++ will very easily invoke undefined behavior, I'm
not sure that a discussion of it is warranted. Yes, many C libraries use
it, but C++ cannot. At least, not without an exceptional degree of care.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_585_1746655141.1432416651527
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, May 23, 2015 at 5:10:32 PM UTC-4, Edw=
ard Catmur wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; What err=
or reporting mechanisms have I missed?
<br>
<br>You haven't mentioned errno; although I'm not sure it counts as a separ=
ate mechanism, it's odd not to see it mentioned. While it's largely an adju=
nct to "special return value", it can also function as an out of band error=
 code:
<br>
<br>&gt; For some system calls and library functions (e.g., getpriority(2))=
,
<br>&gt; &nbsp; &nbsp; &nbsp; -1 is a valid return on success. &nbsp;In suc=
h cases, a successful return
<br>&gt; &nbsp; &nbsp; &nbsp; can be distinguished from an error return by =
setting errno to zero
<br>&gt; &nbsp; &nbsp; &nbsp; before the call, and then, if the call return=
s a status that
<br>&gt; &nbsp; &nbsp; &nbsp; indicates that an error may have occurred, ch=
ecking to see if errno
<br>&gt; &nbsp; &nbsp; &nbsp; has a nonzero value.
<br>- <a href=3D"http://man7.org/linux/man-pages/man3/errno.3.html" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.=
com/url?q\75http%3A%2F%2Fman7.org%2Flinux%2Fman-pages%2Fman3%2Ferrno.3.html=
\46sa\75D\46sntz\0751\46usg\75AFQjCNHPJZzw3veI0BayzYVkIX1M-wlvpg';return tr=
ue;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fman=
7.org%2Flinux%2Fman-pages%2Fman3%2Ferrno.3.html\46sa\75D\46sntz\0751\46usg\=
75AFQjCNHPJZzw3veI0BayzYVkIX1M-wlvpg';return true;">http://man7.org/linux/m=
an-<wbr>pages/man3/errno.3.html</a>
<br>
<br></blockquote><div><br>`errno` is purely an out-of-band error reporting =
scheme. However, you could combine any out-of-band scheme with the special =
return values. The SRV signals the error, and the out-of-band state explain=
s its nature. I should mention that when discussing SRVs.<br>&nbsp;</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">Another important mechanism, tho=
ugh without support in modern languages, is FORTRAN-style alternate return =
- passing in (an) alternative program location(s) to return to. Dijkstra di=
sliked it, of course, along with multiple entry, but with appropriate synta=
ctic structure I think it could actually work in C++. See <a href=3D"http:/=
/programmers.stackexchange.com/a/118793" target=3D"_blank" rel=3D"nofollow"=
 onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fpro=
grammers.stackexchange.com%2Fa%2F118793\46sa\75D\46sntz\0751\46usg\75AFQjCN=
ETi2HmcX6gwbijB1fXg_Ib0aHWuA';return true;" onclick=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fprogrammers.stackexchange.com%2Fa%2F118=
793\46sa\75D\46sntz\0751\46usg\75AFQjCNETi2HmcX6gwbijB1fXg_Ib0aHWuA';return=
 true;">http://programmers.<wbr>stackexchange.com/a/118793</a>
<br></blockquote><div><br>Since such a thing doesn't really work in C++ as =
it currently stands, I don't think it's appropriate for discussion. I'm not=
 trying to catalog every possible mechanism for handling errors, only the o=
nes that can be used in C++.<br>&nbsp;</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">Also, how would you classify setjmp/longjmp? I'm fairly sure =
there are still some C libraries that use it as their preferred error handl=
ing technique. Clearly it's similar to exceptions in that both are stack ba=
sed non local return, but there's plenty of differences, unwinding being ju=
st one</blockquote><div><br>Since using longjmp in C++ will very easily inv=
oke undefined behavior, I'm not sure that a discussion of it is warranted. =
Yes, many C libraries use it, but C++ cannot. At least, not without an exce=
ptional degree of care.<br></div></div>

<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 />

------=_Part_585_1746655141.1432416651527--
------=_Part_584_117271920.1432416651527--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 29 May 2015 07:41:25 +0200
Raw View
This is a multi-part message in MIME format.
--------------030601040509020906080209
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 23/05/15 19:07, Nicol Bolas a =C3=A9crit :
> On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet=20
> Escriba wrote:
>
>     Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>>     On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:
>>
>>         On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas
>>         <jmck...@gmail.com> wrote:
>>         > I just want to see the "sto*" functions get string_view
>>         ASAP. We shouldn't
>>         > wait on `expected` just to accomplish that.
>>
>>         That seems like a straightforward paper to get through the
>>         committee.
>>         If you write it, I'll try to prevent the group from creeping its
>>         scope.
>>
>>
>>     Actually, that paper already exists (N4015
>>     <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>)=
,
>>     with a revision (N4109
>>     <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>)=
..
>>     According to Vicente Escriba, who both wrote those proposals and
>>     replied here, scope creep has already started. Also, N4109 has
>>     been a while ago (almost a year now), with no followup paper from
>>     any discussions based on it.
>>
>     Yes its me. There is an error on the web page that I have already
>     reported. My name is Vicente J. Botet Escriba. Vicente J. is my
>     fisrt name and Botet Escriba is my last name.
>
>     The expected proposal was blocked as the expected proposal was
>     proposing an alternative way to report errors and the standard C++
>     has already one: exceptions. A study of all the alternative ways
>     to reporting errors was requested so we can take a decision on
>     which ones could be used once the advantages and liabilities of
>     each approach are detailed. I'm not a paper writer and writing
>     such a paper needs to be done carefully and it would takes time.
>     If there are any volunteers to write it, please do it, it will be
>     a pleasure to help. Of course, I will be very happy is this paper
>     unblocks the expected proposal.
>
>
> To help support this, I have written the attached rough draft=20
> document. It attempts to be a survey of as many error reporting=20
> mechanisms as possible. This document is /attempting/ to be purely=20
> factual, with as little bias as possible. As such, it doesn't have a=20
> "pros/cons" list, as what might be a "pro" for one application is a=20
> "con" for another. It tries to be descriptive of each method, along=20
> several use cases, without stumping for or arguing against any=20
> particular one.
>
> Note that the document is fairly lengthy, as there are quite a few=20
> ways to go about reporting errors to users, and there are a lot of=20
> consequences for difference schemes of error handling and resolution.
>
> As this is a very rough draft, I'm interested in commentary in the=20
> following areas:
>
> * What error reporting mechanisms have I missed?
>
> * I examine all of the error mechanisms in the context of 3 broad=20
> use-cases: 1) what you do to resolve errors locally, 2) what you do to=20
> resolve errors non-locally even across threads, 3) what you do to=20
> ignore an error entirely, with a discussion of how you might find=20
> places where you've ignored an error by accident. What other=20
> dimensions/use cases could be useful for analyzing them?
>
> * When examining one of the error mechanisms, have I missed some=20
> important way that it interacts with one of the use cases?
>
> * General mistakes/misconceptions/gross biases/rampaging stupidities=20
> at work.
>
Hi and thanks for writing this report.

There is a specialization of the variant return type that makes easier=20
the error propagation. This needs some language changes as e.g. the=20
proposed *await*/*yield* operator. This syntactic sugar approach helps=20
on error propagation (non-local error resolution) in an almost=20
transparent way, so the user doesn't need to check directly if there is=20
an error or not in order to propagate it. All it needs is to say using=20
the await operator if the expression can return a error or not.

|auto exp_value =3D*await*  TargetFunc(...);
|

The await operator is telling the compiler that the result of the=20
expression contains possibly an error that needs some specific handling=20
(See the resumable functions proposal). Even if the main case of the=20
resumable functions proposal is to manage asynchronous cases, there is=20
no reason to don't use it synchronously. Gor has already show this cases=20
in his proposal.

Even if more complex, the idea is that the function must return some=20
wrapped type W<T>.
The await expression

| auto exp_value =3D await TargetFunc(...);
|

is transformed to something like

| auto exp_value =3D TargetFunc(...);
 if(!exp_value)
 {
       return exp_value.error();
 }|


and the yield expression

*yield* a;

makes use in some way of the explicit constructor of the return type.

     return W<T>(a);

IMO, the major advantage to returning a variant type is that we can add=20
syntactic sugar on top of this general interface.
The single question is how easy is it to tell to the compiler that your=20
wrapped type supports the required model.

In a pure functional language as Haskell the single thing required is to=20
be an instance of a Monad. C++ is much more complex and needs a more=20
complex model as the await and yield operator can appear in in place of=20
any expression or return statement respectively. This means that=20
restricting the places where these operators can be used can require a=20
simpler and why not more efficient mapping. These could provided as a=20
QOI of the compiler implementation.

If the resumable functions proposal were adopted by the C++ standard, we=20
will see a lot of libraries that will adapt their types to this new=20
mechanism. I don't see how the standard library would not do the same.

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/.

--------------030601040509020906080209
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 text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 23/05/15 19:07, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:4146760a-2165-4831-8bd4-f7261982b2c5@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4,
        Vicente J. Botet Escriba wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <div>Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit=C2=A0:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM
                UTC-4, Jeffrey Yasskin wrote:
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">On Mon, May 18, 2015 at 2:57
                  PM, Nicol Bolas &lt;<a moz-do-not-send=3D"true"
                    rel=3D"nofollow">jmck...@gmail.com</a>&gt; wrote: <br>
                  &gt; I just want to see the "sto*" functions get
                  string_view ASAP. We shouldn't <br>
                  &gt; wait on `expected` just to accomplish that. <br>
                  <br>
                  That seems like a straightforward paper to get through
                  the committee. <br>
                  If you write it, I'll try to prevent the group from
                  creeping its <br>
                  scope. <br>
                </blockquote>
                <div><br>
                  Actually, that paper already exists (<a
                    moz-do-not-send=3D"true"
                    href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/pap=
ers/2014/n4015.pdf"
                    target=3D"_blank" rel=3D"nofollow"
                    onmousedown=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F201=
4%2Fn4015.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZB=
ZQ';return
                    true;"
                    onclick=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2F=
n4015.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';=
return
                    true;">N4015</a>), with a revision (<a
                    moz-do-not-send=3D"true"
                    href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/pap=
ers/2014/n4109.pdf"
                    target=3D"_blank" rel=3D"nofollow"
                    onmousedown=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F201=
4%2Fn4109.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc=
0A';return
                    true;"
                    onclick=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2F=
n4109.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';=
return
                    true;">N4109</a>). According to Vicente Escriba, who
                  both wrote those proposals and replied here, scope
                  creep has already started. Also, N4109 has been a
                  while ago (almost a year now), with no followup paper
                  from any discussions based on it.<br>
                  <br>
                </div>
              </div>
            </blockquote>
            Yes its me. There is an error on the web page that I have
            already reported. My name is Vicente J. Botet Escriba.
            Vicente J. is my fisrt name and Botet Escriba is my last
            name. <br>
            <br>
            The expected proposal was blocked as the expected proposal
            was proposing an alternative way to report errors and the
            standard C++ has already one: exceptions. A study of all the
            alternative ways to reporting errors was requested so we can
            take a decision on which ones could be used once the
            advantages and liabilities of each approach are detailed.
            I'm not a paper writer and writing such a paper needs to be
            done carefully and it would takes time. If there are any
            volunteers to write it, please do it, it will be a pleasure
            to help. Of course, I will be very happy is this paper
            unblocks the expected proposal.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        To help support this, I have written the attached rough draft
        document. It attempts to be a survey of as many error reporting
        mechanisms as possible. This document is <i>attempting</i> to
        be purely factual, with as little bias as possible. As such, it
        doesn't have a "pros/cons" list, as what might be a "pro" for
        one application is a "con" for another. It tries to be
        descriptive of each method, along several use cases, without
        stumping for or arguing against any particular one.<br>
        <br>
        Note that the document is fairly lengthy, as there are quite a
        few ways to go about reporting errors to users, and there are a
        lot of consequences for difference schemes of error handling and
        resolution.<br>
        <br>
        As this is a very rough draft, I'm interested in commentary in
        the following areas:<br>
        <br>
        * What error reporting mechanisms have I missed?<br>
        <br>
        * I examine all of the error mechanisms in the context of 3
        broad use-cases: 1) what you do to resolve errors locally, 2)
        what you do to resolve errors non-locally even across threads,
        3) what you do to ignore an error entirely, with a discussion of
        how you might find places where you've ignored an error by
        accident. What other dimensions/use cases could be useful for
        analyzing them?<br>
        <br>
        * When examining one of the error mechanisms, have I missed some
        important way that it interacts with one of the use cases?<br>
        <br>
        * General mistakes/misconceptions/gross biases/rampaging
        stupidities at work.<br>
      </div>
      <br>
    </blockquote>
    Hi and thanks for writing this report.<br>
    <br>
    There is a specialization of the variant return type that makes
    easier the error propagation. This needs some language changes as
    e.g. the proposed <b>await</b>/<b>yield</b> operator. This
    syntactic sugar approach helps on error propagation (non-local error
    resolution) in an almost transparent way, so the user doesn't need
    to check directly if there is an error or not in order to propagate
    it. All it needs is to say using the await operator if the
    expression can return a error or not.<br>
    <br>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    <pre><code>auto exp_value =3D <b>await</b> TargetFunc(...);
</code>
</pre>
    The await operator is telling the compiler that the result of the
    expression contains possibly an error that needs some specific
    handling (See the resumable functions proposal). Even if the main
    case of the resumable functions proposal is to manage asynchronous
    cases, there is no reason to don't use it synchronously. Gor has
    already show this cases in his proposal.<br>
    <br>
    Even if more complex, the idea is that the function must return some
    wrapped type W&lt;T&gt;.<br>
    The await expression <br>
    <pre><code> auto exp_value =3D await TargetFunc(...);
</code></pre>
    is transformed to something like<br>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    <pre><code> auto exp_value =3D TargetFunc(...);
 if(!exp_value)
 {
      return exp_value.error();
 }</code></pre>
    <br>
    and the yield expression <br>
    <br>
    =C2=A0=C2=A0=C2=A0 <b>yield</b> a;<br>
    <br>
    makes use in some way of the explicit constructor of the return
    type.<br>
    <br>
    =C2=A0=C2=A0=C2=A0 return W&lt;T&gt;(a);<br>
    =C2=A0<br>
    IMO, the major advantage to returning a variant type is that we can
    add syntactic sugar on top of this general interface.<br>
    The single question is how easy is it to tell to the compiler that
    your wrapped type supports the required model.<br>
    <br>
    In a pure functional language as Haskell the single thing required
    is to be an instance of a Monad. C++ is much more complex and needs
    a more complex model as the await and yield operator can appear in
    in place of any expression or return statement respectively. This
    means that restricting the places where these operators can be used
    can require a simpler and why not more efficient mapping. These
    could provided as a QOI of the compiler implementation.<br>
    =C2=A0<br>
    If the resumable functions proposal were adopted by the C++
    standard, we will see a lot of libraries that will adapt their types
    to this new mechanism. I don't see how the standard library would
    not do the same.<br>
    <br>
    Vicente<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 />

--------------030601040509020906080209--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 29 May 2015 00:05:59 -0700 (PDT)
Raw View
------=_Part_248_2017083451.1432883159999
Content-Type: multipart/alternative;
 boundary="----=_Part_249_944709415.1432883159999"

------=_Part_249_944709415.1432883159999
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Friday, May 29, 2015 at 1:41:29 AM UTC-4, Vicente J. Botet Escriba wrote=
:
>
>  Le 23/05/15 19:07, Nicol Bolas a =C3=A9crit :
> =20
> On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet Escriba=
=20
> wrote:=20
>>
>>  Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>> =20
>> On Monday, May 18, 2015 at 6:30:38 PM UTC-4, Jeffrey Yasskin wrote:=20
>>>
>>> On Mon, May 18, 2015 at 2:57 PM, Nicol Bolas <jmck...@gmail.com> wrote:=
=20
>>> > I just want to see the "sto*" functions get string_view ASAP. We=20
>>> shouldn't=20
>>> > wait on `expected` just to accomplish that.=20
>>>
>>> That seems like a straightforward paper to get through the committee.=
=20
>>> If you write it, I'll try to prevent the group from creeping its=20
>>> scope.=20
>>>
>>
>> Actually, that paper already exists (N4015=20
>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf>),=20
>> with a revision (N4109=20
>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4109.pdf>).=20
>> According to Vicente Escriba, who both wrote those proposals and replied=
=20
>> here, scope creep has already started. Also, N4109 has been a while ago=
=20
>> (almost a year now), with no followup paper from any discussions based o=
n=20
>> it.
>>
>>   Yes its me. There is an error on the web page that I have already=20
>> reported. My name is Vicente J. Botet Escriba. Vicente J. is my fisrt na=
me=20
>> and Botet Escriba is my last name.=20
>>
>> The expected proposal was blocked as the expected proposal was proposing=
=20
>> an alternative way to report errors and the standard C++ has already one=
:=20
>> exceptions. A study of all the alternative ways to reporting errors was=
=20
>> requested so we can take a decision on which ones could be used once the=
=20
>> advantages and liabilities of each approach are detailed. I'm not a pape=
r=20
>> writer and writing such a paper needs to be done carefully and it would=
=20
>> takes time. If there are any volunteers to write it, please do it, it wi=
ll=20
>> be a pleasure to help. Of course, I will be very happy is this paper=20
>> unblocks the expected proposal.
>> =20
>
>  To help support this, I have written the attached rough draft document.=
=20
> It attempts to be a survey of as many error reporting mechanisms as=20
> possible. This document is *attempting* to be purely factual, with as=20
> little bias as possible. As such, it doesn't have a "pros/cons" list, as=
=20
> what might be a "pro" for one application is a "con" for another. It trie=
s=20
> to be descriptive of each method, along several use cases, without stumpi=
ng=20
> for or arguing against any particular one.
>
> Note that the document is fairly lengthy, as there are quite a few ways t=
o=20
> go about reporting errors to users, and there are a lot of consequences f=
or=20
> difference schemes of error handling and resolution.
>
> As this is a very rough draft, I'm interested in commentary in the=20
> following areas:
>
> * What error reporting mechanisms have I missed?
>
> * I examine all of the error mechanisms in the context of 3 broad=20
> use-cases: 1) what you do to resolve errors locally, 2) what you do to=20
> resolve errors non-locally even across threads, 3) what you do to ignore =
an=20
> error entirely, with a discussion of how you might find places where you'=
ve=20
> ignored an error by accident. What other dimensions/use cases could be=20
> useful for analyzing them?
>
> * When examining one of the error mechanisms, have I missed some importan=
t=20
> way that it interacts with one of the use cases?
>
> * General mistakes/misconceptions/gross biases/rampaging stupidities at=
=20
> work.
> =20
>  Hi and thanks for writing this report.
>
> There is a specialization of the variant return type that makes easier th=
e=20
> error propagation. This needs some language changes as e.g. the proposed=
=20
> *await*/*yield* operator. This syntactic sugar approach helps on error=20
> propagation (non-local error resolution) in an almost transparent way, so=
=20
> the user doesn't need to check directly if there is an error or not in=20
> order to propagate it. All it needs is to say using the await operator if=
=20
> the expression can return a error or not.
>
> auto exp_value =3D *await* TargetFunc(...);
>
> The await operator is telling the compiler that the result of the=20
> expression contains possibly an error that needs some specific handling=
=20
> (See the resumable functions proposal). Even if the main case of the=20
> resumable functions proposal is to manage asynchronous cases, there is no=
=20
> reason to don't use it synchronously.
>

I admit that my knowledge of this feature is limited to a presentation Herb=
=20
made well over a year ago, when talking about Visual Studio having a=20
preliminary implementation of "async/await". Obviously, things have=20
progressed in a rather different direction, since one of the features=20
(async) isn't there anymore and something else is (yield). So feel free to=
=20
correct me if I'm wrong.

But isn't issuing some form of coroutine at least marginally expensive?=20
Compared to a regular function call, that is.

I mean, let's take the case of a generalized "parse" function, to which you=
=20
pass a generalized file IO system. So you're parsing from a file.

The code using the parse function will `await` on it. But the parse=20
function should also `await` on the file IO system it's been given, since=
=20
that can error too. Any errors it gets are propagated to the caller. So=20
that's two `await` overheads, all just to propagate the error.

By contrast, the overhead for exceptions is paid for with `try` blocks, at=
=20
the site where you're actually resolving the error. And the runtime cost is=
=20
paid only when you actually throw, not simply because you *might* throw.=20
And you don't have to stick `await` in every place that might result in an=
=20
error.

I don't really see the advantage over exceptions here.

Gor has already show this cases in his proposal.
>
> Even if more complex, the idea is that the function must return some=20
> wrapped type W<T>.
> The await expression=20
>
>  auto exp_value =3D await TargetFunc(...);
>
> is transformed to something like
>
>  auto exp_value =3D TargetFunc(...);
>  if(!exp_value)
>  {
>       return exp_value.error();
>  }
>
>
> and the yield expression=20
>
>     *yield* a;
>
> makes use in some way of the explicit constructor of the return type.
>
>     return W<T>(a);
> =20
> IMO, the major advantage to returning a variant type is that we can add=
=20
> syntactic sugar on top of this general interface.
>

Is that what is actually part of that proposal, or is that what you're=20
*suggesting* should be done? If it's the latter, I would be very much=20
against that. You shouldn't try to slap unrelated constructs into other=20
proposals just because they might be able to work there. Resumable=20
functions is about functions that can be suspended and resumed; giving them=
=20
special properties, such that the compiler actually generates code that has=
=20
certain expectations on the user (like the return type of the current=20
function) feels really arbitrary.

Especially when we already have an adequate solution to the problem of=20
returning errors to locations in code defined by the caller. One that=20
requires zero local syntax.

Also, if you can't get people to let `return {x};` use explicit=20
constructors, I fail to see how you can get them to agree that `yield x;`=
=20
will. That'd be remarkably inconsistent.

If the resumable functions proposal were adopted by the C++ standard, we=20
> will see a lot of libraries that will adapt their types to this new=20
> mechanism. I don't see how the standard library would not do the same.
>

As I understand what you're discussing, the await/yield syntax you're=20
suggesting is a form of syntactic sugar which is useful for propagating an=
=20
error to a higher level with less apparent code. So while the direct=20
syntactic burden at the local level is lessened (no need for an explicit=20
conditional), the rest of it is still there.

So what you're suggesting would only be widely adopted if the reason=20
everyone was avoiding `expected` beforehand was due to having to explicitly=
=20
test the conditional, just to propagate the error to the higher level.

I don't think that's the case. I'm rather sure that `expected` will be=20
widely adopted or not based on its own merits, not this specific scenario.

>

--=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/.

------=_Part_249_944709415.1432883159999
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, May 29, 2015 at 1:41:29 AM UTC-4, Vicen=
te J. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>Le 23/05/15 19:07, Nicol Bolas a
      =C3=A9crit&nbsp;:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4,
        Vicente J. Botet Escriba wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <div>Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit&nbsp;:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Monday, May 18, 2015 at 6:30:38 PM
                UTC-4, Jeffrey Yasskin wrote:
                <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Mon, May 18, 201=
5 at 2:57
                  PM, Nicol Bolas &lt;<a rel=3D"nofollow">jmck...@gmail.com=
</a>&gt; wrote: <br>
                  &gt; I just want to see the "sto*" functions get
                  string_view ASAP. We shouldn't <br>
                  &gt; wait on `expected` just to accomplish that. <br>
                  <br>
                  That seems like a straightforward paper to get through
                  the committee. <br>
                  If you write it, I'll try to prevent the group from
                  creeping its <br>
                  scope. <br>
                </blockquote>
                <div><br>
                  Actually, that paper already exists (<a href=3D"http://ww=
w.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4015.pdf" rel=3D"nofollow" =
target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%=
2Fn4015.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ=
';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn401=
5.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEb2_rBQ9RLLLeewV92NGz0j9ZBZQ';retu=
rn true;">N4015</a>), with a revision (<a href=3D"http://www.open-std.org/J=
TC1/SC22/WG21/docs/papers/2014/n4109.pdf" rel=3D"nofollow" target=3D"_blank=
" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fww=
w.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa=
\75D\46sntz\0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;" =
onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open=
-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn4109.pdf\46sa\75D\4=
6sntz\0751\46usg\75AFQjCNGSuEfsBLroka4AbDKY8FFE0pHc0A';return true;">N4109<=
/a>). According to Vicente Escriba, who
                  both wrote those proposals and replied here, scope
                  creep has already started. Also, N4109 has been a
                  while ago (almost a year now), with no followup paper
                  from any discussions based on it.<br>
                  <br>
                </div>
              </div>
            </blockquote>
            Yes its me. There is an error on the web page that I have
            already reported. My name is Vicente J. Botet Escriba.
            Vicente J. is my fisrt name and Botet Escriba is my last
            name. <br>
            <br>
            The expected proposal was blocked as the expected proposal
            was proposing an alternative way to report errors and the
            standard C++ has already one: exceptions. A study of all the
            alternative ways to reporting errors was requested so we can
            take a decision on which ones could be used once the
            advantages and liabilities of each approach are detailed.
            I'm not a paper writer and writing such a paper needs to be
            done carefully and it would takes time. If there are any
            volunteers to write it, please do it, it will be a pleasure
            to help. Of course, I will be very happy is this paper
            unblocks the expected proposal.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        To help support this, I have written the attached rough draft
        document. It attempts to be a survey of as many error reporting
        mechanisms as possible. This document is <i>attempting</i> to
        be purely factual, with as little bias as possible. As such, it
        doesn't have a "pros/cons" list, as what might be a "pro" for
        one application is a "con" for another. It tries to be
        descriptive of each method, along several use cases, without
        stumping for or arguing against any particular one.<br>
        <br>
        Note that the document is fairly lengthy, as there are quite a
        few ways to go about reporting errors to users, and there are a
        lot of consequences for difference schemes of error handling and
        resolution.<br>
        <br>
        As this is a very rough draft, I'm interested in commentary in
        the following areas:<br>
        <br>
        * What error reporting mechanisms have I missed?<br>
        <br>
        * I examine all of the error mechanisms in the context of 3
        broad use-cases: 1) what you do to resolve errors locally, 2)
        what you do to resolve errors non-locally even across threads,
        3) what you do to ignore an error entirely, with a discussion of
        how you might find places where you've ignored an error by
        accident. What other dimensions/use cases could be useful for
        analyzing them?<br>
        <br>
        * When examining one of the error mechanisms, have I missed some
        important way that it interacts with one of the use cases?<br>
        <br>
        * General mistakes/misconceptions/gross biases/rampaging
        stupidities at work.<br>
      </div>
      <br>
    </blockquote>
    Hi and thanks for writing this report.<br>
    <br>
    There is a specialization of the variant return type that makes
    easier the error propagation. This needs some language changes as
    e.g. the proposed <b>await</b>/<b>yield</b> operator. This
    syntactic sugar approach helps on error propagation (non-local error
    resolution) in an almost transparent way, so the user doesn't need
    to check directly if there is an error or not in order to propagate
    it. All it needs is to say using the await operator if the
    expression can return a error or not.<br>
    <br>
   =20
    <pre><code>auto exp_value =3D <b>await</b> TargetFunc(...);
</code>
</pre>
    The await operator is telling the compiler that the result of the
    expression contains possibly an error that needs some specific
    handling (See the resumable functions proposal). Even if the main
    case of the resumable functions proposal is to manage asynchronous
    cases, there is no reason to don't use it synchronously.</div></blockqu=
ote><div><br>I admit that my knowledge of this feature is limited to a pres=
entation Herb made well over a year ago, when talking about Visual Studio h=
aving a preliminary implementation of "async/await". Obviously, things have=
 progressed in a rather different direction, since one of the features (asy=
nc) isn't there anymore and something else is (yield). So feel free to corr=
ect me if I'm wrong.<br><br>But isn't issuing some form of coroutine at lea=
st marginally expensive? Compared to a regular function call, that is.<br><=
br>I mean, let's take the case of a generalized "parse" function, to which =
you pass a generalized file IO system. So you're parsing from a file.<br><b=
r>The code using the parse function will `await` on it. But the parse funct=
ion should also `await` on the file IO system it's been given, since that c=
an error too. Any errors it gets are propagated to the caller. So that's tw=
o `await` overheads, all just to propagate the error.<br><br>By contrast, t=
he overhead for exceptions is paid for with `try` blocks, at the site where=
 you're actually resolving the error. And the runtime cost is paid only whe=
n you actually throw, not simply because you <i>might</i> throw. And you do=
n't have to stick `await` in every place that might result in an error.<br>=
<br>I don't really see the advantage over exceptions here.<br><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div text=3D"#000000" bgcolor=3D"=
#FFFFFF"> Gor has
    already show this cases in his proposal.<br>
    <br>
    Even if more complex, the idea is that the function must return some
    wrapped type W&lt;T&gt;.<br>
    The await expression <br>
    <pre><code> auto exp_value =3D await TargetFunc(...);
</code></pre>
    is transformed to something like<br>
   =20
    <pre><code> auto exp_value =3D TargetFunc(...);
 if(!exp_value)
 {
      return exp_value.error();
 }</code></pre>
    <br>
    and the yield expression <br>
    <br>
    &nbsp;&nbsp;&nbsp; <b>yield</b> a;<br>
    <br>
    makes use in some way of the explicit constructor of the return
    type.<br>
    <br>
    &nbsp;&nbsp;&nbsp; return W&lt;T&gt;(a);<br>
    &nbsp;<br>
    IMO, the major advantage to returning a variant type is that we can
    add syntactic sugar on top of this general interface.<br></div></blockq=
uote><div><br>Is that what is actually part of that proposal, or is that wh=
at you're <i>suggesting</i> should be done? If it's the latter, I would be =
very much against that. You shouldn't try to slap unrelated constructs into=
 other proposals just because they might be able to work there. Resumable f=
unctions is about functions that can be suspended and resumed; giving them =
special properties, such that the compiler actually generates code that has=
 certain expectations on the user (like the return type of the current func=
tion) feels really arbitrary.<br><br>Especially when we already have an ade=
quate solution to the problem of=20
returning errors to locations in code defined by the caller. One that requi=
res zero local syntax.<br><br>Also, if you can't get people to let `return =
{x};` use explicit constructors, I fail to see how you can get them to agre=
e that `yield x;` will. That'd be remarkably inconsistent.<br><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div text=3D"#000000" bgcolor=3D"=
#FFFFFF">
    If the resumable functions proposal were adopted by the C++
    standard, we will see a lot of libraries that will adapt their types
    to this new mechanism. I don't see how the standard library would
    not do the same.<br></div></blockquote><div><br>As I understand what yo=
u're discussing, the await/yield syntax you're suggesting is a form of synt=
actic sugar which is useful for propagating an error to a higher level with=
 less apparent code. So while the direct syntactic burden at the local leve=
l is lessened (no need for an explicit conditional), the rest of it is stil=
l there.<br><br>So what you're suggesting would only be widely adopted if t=
he reason everyone was avoiding `expected` beforehand was due to having to =
explicitly test the conditional, just to propagate the error to the higher =
level.<br><br>I don't think that's the case. I'm rather sure that `expected=
` will be widely adopted or not based on its own merits, not this specific =
scenario.<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">

</blockquote></div>

<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 />

------=_Part_249_944709415.1432883159999--
------=_Part_248_2017083451.1432883159999--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 29 May 2015 19:19:02 +0200
Raw View
This is a multi-part message in MIME format.
--------------070606070600080408000106
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 29/05/15 09:05, Nicol Bolas a =C3=A9crit :
>
>
> On Friday, May 29, 2015 at 1:41:29 AM UTC-4, Vicente J. Botet Escriba=20
> wrote:
>
>     Le 23/05/15 19:07, Nicol Bolas a =C3=A9crit :
>>     On Wednesday, May 20, 2015 at 11:09:01 AM UTC-4, Vicente J. Botet
>>     Escriba wrote:
>>
>>         Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit :
>>
>>
>>
>     Hi and thanks for writing this report.
>
>     There is a specialization of the variant return type that makes
>     easier the error propagation. This needs some language changes as
>     e.g. the proposed *await*/*yield* operator. This syntactic sugar
>     approach helps on error propagation (non-local error resolution)
>     in an almost transparent way, so the user doesn't need to check
>     directly if there is an error or not in order to propagate it. All
>     it needs is to say using the await operator if the expression can
>     return a error or not.
>
>     |auto exp_value =3D*await*  TargetFunc(...);
>     |
>
>     The await operator is telling the compiler that the result of the
>     expression contains possibly an error that needs some specific
>     handling (See the resumable functions proposal). Even if the main
>     case of the resumable functions proposal is to manage asynchronous
>     cases, there is no reason to don't use it synchronously.
>
>
> I admit that my knowledge of this feature is limited to a presentation=20
> Herb made well over a year ago, when talking about Visual Studio=20
> having a preliminary implementation of "async/await". Obviously,=20
> things have progressed in a rather different direction, since one of=20
> the features (async) isn't there anymore and something else is=20
> (yield). So feel free to correct me if I'm wrong.
>
> But isn't issuing some form of coroutine at least marginally=20
> expensive? Compared to a regular function call, that is.
It works with coroutines, but not only. See below.
>
> I mean, let's take the case of a generalized "parse" function, to=20
> which you pass a generalized file IO system. So you're parsing from a=20
> file.
>
> The code using the parse function will `await` on it. But the parse=20
> function should also `await` on the file IO system it's been given,=20
> since that can error too. Any errors it gets are propagated to the=20
> caller. So that's two `await` overheads, all just to propagate the error.

IMO, the await on the file IO would be used more to improve the=20
performances than to transport errors.
The await on the file IO will suspend, but I'm not sure the await on the=20
parser needs to suspend. All this depends on whether you want to run the=20
parsing concurrently or not. The await on the file IO is natural, so=20
that we don't block the thread.

Note that the parser function on a string wouldn't suspend at all. It is=20
the nature of the IO device that incur in a suspension when await is=20
used (or a wait otherwise).
>
> By contrast, the overhead for exceptions is paid for with `try`=20
> blocks, at the site where you're actually resolving the error. And the=20
> runtime cost is paid only when you actually throw, not simply because=20
> you /might/ throw. And you don't have to stick `await` in every place=20
> that might result in an error.
Wouldn't your parser function using exceptions use "await" also on the=20
file IO?

You are right that the use of await everywhere is something that the=20
user must pay for. When doing assignments there is a possible syntactic=20
sugar, replacing

| auto exp_value =3D await TargetFunc(...);|

by

| auto exp_value :=3D TargetFunc(...);|

Note that I'm not proposing anything here.
>
> I don't really see the advantage over exceptions here.
I'm not comparing it to exceptions but to error codes. Of course,=20
performance figures are always welcome and needed.
>
>     Gor has already show this cases in his proposal.
>
>     Even if more complex, the idea is that the function must return
>     some wrapped type W<T>.
>     The await expression
>
>     | auto exp_value =3D await TargetFunc(...);
>     |
>
>     is transformed to something like
>
>     | auto exp_value =3D TargetFunc(...);
>      if(!exp_value)
>      {
>            return exp_value.error();
>      }|
>
>
>     and the yield expression
>
>     *yield* a;
>
>     makes use in some way of the explicit constructor of the return type.
>
>         return W<T>(a);
>
>     IMO, the major advantage to returning a variant type is that we
>     can add syntactic sugar on top of this general interface.
>
>
> Is that what is actually part of that proposal, or is that what you're=20
> /suggesting/ should be done?
I said "in some way". That means that I don't included the details.
> If it's the latter, I would be very much against that.
So if it is in the proposal you are for and if it is me that I'm=20
suggesting what should be done you are against. I'm sure you wanted to=20
say something else. Anyway, to what you would be against and why?
> You shouldn't try to slap unrelated constructs into other proposals=20
> just because they might be able to work there.
I believe that the proposal includes this kind of usage, maybe Gor can=20
infirm.
> Resumable functions is about functions that can be suspended and=20
> resumed; giving them special properties, such that the compiler=20
> actually generates code that has certain expectations on the user=20
> (like the return type of the current function) feels really arbitrary.
I believe that the proposal takes in account this synchronous case, and=20
in this case the call to suspend does nothing.
>
> Especially when we already have an adequate solution to the problem of=20
> returning errors to locations in code defined by the caller. One that=20
> requires zero local syntax.
Again, I'm not comparing it to exceptions, but to interfaces using=20
directly error codes.
>
> Also, if you can't get people to let `return {x};` use explicit=20
> constructors, I fail to see how you can get them to agree that `yield=20
> x;` will. That'd be remarkably inconsistent.
I believe the proposal includes this. I don't remember if with return or=20
with yield.
>
>     If the resumable functions proposal were adopted by the C++
>     standard, we will see a lot of libraries that will adapt their
>     types to this new mechanism. I don't see how the standard library
>     would not do the same.
>
>
> As I understand what you're discussing, the await/yield syntax you're=20
> suggesting
It is not me that suggested that syntax, but Gor & all. It corresponds=20
to the C++ way for the monadic do notation adapted to C++. It is more=20
powerful than the do notation, and as consequence the mapping is more=20
complex. But this mapping is done one for all.
> is a form of syntactic sugar which is useful for propagating an error=20
> to a higher level with less apparent code. So while the direct=20
> syntactic burden at the local level is lessened (no need for an=20
> explicit conditional), the rest of it is still there.
>
Right. The await/yield syntax could be adapted to any monad. As expected=20
can be seen as one monad it can be adapted. But await/yield can be used=20
with other monads that are not used to transport errors.  While the=20
original proposal worked only with functions returning futures, the last=20
version adapted it to work with functions that return any type that can=20
be mapped to some specific contraints.
> So what you're suggesting would only be widely adopted if the reason=20
> everyone was avoiding `expected` beforehand was due to having to=20
> explicitly test the conditional, just to propagate the error to the=20
> higher level.
I don't think this is the single reason, but it could be a reason to=20
dislike expected, future, ...
The C++community use to program using imperative style. The syntactic=20
sugar makes it more adapted to this style.
>
> I don't think that's the case. I'm rather sure that `expected` will be=20
> widely adopted or not based on its own merits, not this specific scenario=
..
>
>
I believe expected is useful by itself. However its monadic nature makes=20
it useful in more contexts than when we look at it alone. At the end, I=20
worry more for the reasons why it is not adopted than the reasons=20
explaining why it is adopted.

Haskell.Scala/F# have added some kind of syntactic sugar because it=20
simplifies a lot the reading of the code. C++ is not Haskell/Scala/F#,=20
but once you have this syntactic sugar I believe that most of the users=20
will prefer to use it.


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/.

--------------070606070600080408000106
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 29/05/15 09:05, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Friday, May 29, 2015 at 1:41:29 AM UTC-4, Vicente J. Botet
        Escriba wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <div>Le 23/05/15 19:07, Nicol Bolas a =C3=A9crit=C2=A0:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Wednesday, May 20, 2015 at 11:09:01 AM
                UTC-4, Vicente J. Botet Escriba wrote:
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">
                  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
                    <div>Le 19/05/15 03:01, Nicol Bolas a =C3=A9crit=C2=A0:=
<br>
                    </div>
                    <br>
                  </div>
                </blockquote>
                <br>
              </div>
              <br>
            </blockquote>
            Hi and thanks for writing this report.<br>
            <br>
            There is a specialization of the variant return type that
            makes easier the error propagation. This needs some language
            changes as e.g. the proposed <b>await</b>/<b>yield</b>
            operator. This syntactic sugar approach helps on error
            propagation (non-local error resolution) in an almost
            transparent way, so the user doesn't need to check directly
            if there is an error or not in order to propagate it. All it
            needs is to say using the await operator if the expression
            can return a error or not.<br>
            <br>
            <pre><code>auto exp_value =3D <b>await</b> TargetFunc(...);
</code>
</pre>
            The await operator is telling the compiler that the result
            of the expression contains possibly an error that needs some
            specific handling (See the resumable functions proposal).
            Even if the main case of the resumable functions proposal is
            to manage asynchronous cases, there is no reason to don't
            use it synchronously.</div>
        </blockquote>
        <div><br>
          I admit that my knowledge of this feature is limited to a
          presentation Herb made well over a year ago, when talking
          about Visual Studio having a preliminary implementation of
          "async/await". Obviously, things have progressed in a rather
          different direction, since one of the features (async) isn't
          there anymore and something else is (yield). So feel free to
          correct me if I'm wrong.<br>
          <br>
          But isn't issuing some form of coroutine at least marginally
          expensive? Compared to a regular function call, that is.<br>
        </div>
      </div>
    </blockquote>
    It works with coroutines, but not only. See below.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          I mean, let's take the case of a generalized "parse" function,
          to which you pass a generalized file IO system. So you're
          parsing from a file.<br>
          <br>
          The code using the parse function will `await` on it. But the
          parse function should also `await` on the file IO system it's
          been given, since that can error too. Any errors it gets are
          propagated to the caller. So that's two `await` overheads, all
          just to propagate the error.<br>
        </div>
      </div>
    </blockquote>
    <br>
    IMO, the await on the file IO would be used more to improve the
    performances than to transport errors.<br>
    The await on the file IO will suspend, but I'm not sure the await on
    the parser needs to suspend. All this depends on whether you want to
    run the parsing concurrently or not. The await on the file IO is
    natural, so that we don't block the thread.<br>
    <br>
    Note that the parser function on a string wouldn't suspend at all.
    It is the nature of the IO device that incur in a suspension when
    await is used (or a wait otherwise).<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          By contrast, the overhead for exceptions is paid for with
          `try` blocks, at the site where you're actually resolving the
          error. And the runtime cost is paid only when you actually
          throw, not simply because you <i>might</i> throw. And you
          don't have to stick `await` in every place that might result
          in an error.<br>
        </div>
      </div>
    </blockquote>
    Wouldn't your parser function using exceptions use "await" also on
    the file IO?<br>
    <br>
    You are right that the use of await everywhere is something that the
    user must pay for. When doing assignments there is a possible
    syntactic sugar, replacing<br>
    <pre><code> auto exp_value =3D await TargetFunc(...);</code></pre>
    by<br>
    <pre><code> auto exp_value :=3D TargetFunc(...);</code></pre>
    Note that I'm not proposing anything here.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          I don't really see the advantage over exceptions here.<br>
        </div>
      </div>
    </blockquote>
    I'm not comparing it to exceptions but to error codes. Of course,
    performance figures are always welcome and needed. <br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF"> Gor has already show
            this cases in his proposal.<br>
            <br>
            Even if more complex, the idea is that the function must
            return some wrapped type W&lt;T&gt;.<br>
            The await expression <br>
            <pre><code> auto exp_value =3D await TargetFunc(...);
</code></pre>
            is transformed to something like<br>
            <pre><code> auto exp_value =3D TargetFunc(...);
 if(!exp_value)
 {
      return exp_value.error();
 }</code></pre>
            <br>
            and the yield expression <br>
            <br>
            =C2=A0=C2=A0=C2=A0 <b>yield</b> a;<br>
            <br>
            makes use in some way of the explicit constructor of the
            return type.<br>
            <br>
            =C2=A0=C2=A0=C2=A0 return W&lt;T&gt;(a);<br>
            =C2=A0<br>
            IMO, the major advantage to returning a variant type is that
            we can add syntactic sugar on top of this general interface.<br=
>
          </div>
        </blockquote>
        <div><br>
          Is that what is actually part of that proposal, or is that
          what you're <i>suggesting</i> should be done? </div>
      </div>
    </blockquote>
    I said "in some way". That means that I don't included the details.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>If it's the latter, I would be very much against that. </div>
      </div>
    </blockquote>
    So if it is in the proposal you are for and if it is me that I'm
    suggesting what should be done you are against. I'm sure you wanted
    to say something else. Anyway, to what you would be against and why?<br=
>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>You shouldn't try to slap unrelated constructs into other
          proposals just because they might be able to work there. </div>
      </div>
    </blockquote>
    I believe that the proposal includes this kind of usage, maybe Gor
    can infirm.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>Resumable functions is about functions that can be
          suspended and resumed; giving them special properties, such
          that the compiler actually generates code that has certain
          expectations on the user (like the return type of the current
          function) feels really arbitrary.<br>
        </div>
      </div>
    </blockquote>
    I believe that the proposal takes in account this synchronous case,
    and in this case the call to suspend does nothing.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          Especially when we already have an adequate solution to the
          problem of returning errors to locations in code defined by
          the caller. One that requires zero local syntax.<br>
        </div>
      </div>
    </blockquote>
    Again, I'm not comparing it to exceptions, but to interfaces using
    directly error codes.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          Also, if you can't get people to let `return {x};` use
          explicit constructors, I fail to see how you can get them to
          agree that `yield x;` will. That'd be remarkably inconsistent.<br=
>
        </div>
      </div>
    </blockquote>
    I believe the proposal includes this. I don't remember if with
    return or with yield.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF"> If the resumable
            functions proposal were adopted by the C++ standard, we will
            see a lot of libraries that will adapt their types to this
            new mechanism. I don't see how the standard library would
            not do the same.<br>
          </div>
        </blockquote>
        <div><br>
          As I understand what you're discussing, the await/yield syntax
          you're suggesting </div>
      </div>
    </blockquote>
    It is not me that suggested that syntax, but Gor &amp; all. It
    corresponds to the C++ way for the monadic do notation adapted to
    C++. It is more powerful than the do notation, and as consequence
    the mapping is more complex. But this mapping is done one for all.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>is a form of syntactic sugar which is useful for
          propagating an error to a higher level with less apparent
          code. So while the direct syntactic burden at the local level
          is lessened (no need for an explicit conditional), the rest of
          it is still there.<br>
          <br>
        </div>
      </div>
    </blockquote>
    Right. The await/yield syntax could be adapted to any monad. As
    expected can be seen as one monad it can be adapted. But await/yield
    can be used with other monads that are not used to transport
    errors.=C2=A0 While the original proposal worked only with functions
    returning futures, the last version adapted it to work with
    functions that return any type that can be mapped to some specific
    contraints.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>So what you're suggesting would only be widely adopted if
          the reason everyone was avoiding `expected` beforehand was due
          to having to explicitly test the conditional, just to
          propagate the error to the higher level.<br>
        </div>
      </div>
    </blockquote>
    I don't think this is the single reason, but it could be a reason to
    dislike expected, future, ...<br>
    The C++community use to program using imperative style. The
    syntactic sugar makes it more adapted to this style.<br>
    <blockquote
      cite=3D"mid:83156640-1e04-4b2d-88ea-023a0f7362fd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          I don't think that's the case. I'm rather sure that `expected`
          will be widely adopted or not based on its own merits, not
          this specific scenario.<br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
        </blockquote>
      </div>
      <br>
    </blockquote>
    I believe expected is useful by itself. However its monadic nature
    makes it useful in more contexts than when we look at it alone. At
    the end, I worry more for the reasons why it is not adopted than the
    reasons explaining why it is adopted.<br>
    <br>
    Haskell.Scala/F# have added some kind of syntactic sugar because it
    simplifies a lot the reading of the code. C++ is not
    Haskell/Scala/F#, but once you have this syntactic sugar I believe
    that most of the users will prefer to use it. <br>
    <br>
    <br>
    Vicente<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 />

--------------070606070600080408000106--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 29 May 2015 17:04:57 -0700 (PDT)
Raw View
------=_Part_1121_243278793.1432944297532
Content-Type: multipart/alternative;
 boundary="----=_Part_1122_2125293710.1432944297533"

------=_Part_1122_2125293710.1432944297533
Content-Type: text/plain; charset=UTF-8

Er, it seems clear that I don't really understand the resumable functions
proposal sufficiently well to discuss it intelligently. I assumed that
`await`ing on a function meant that you were calling a coroutine or
something (regardless of whether it's synchronous or asynchronous).

Since I don't understand what the keywords actually do, how resumable
functions work, or anything of the like, I can't really talk about how they
impact error handling with regard to optional/expected.

I'll take some time in the future to learn more about it before commenting
further.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1122_2125293710.1432944297533
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Er, it seems clear that I don't really understand the resu=
mable functions proposal sufficiently well to discuss it intelligently. I a=
ssumed that `await`ing on a function meant that you were calling a coroutin=
e or something (regardless of whether it's synchronous or asynchronous).<br=
><br>Since I don't understand what the keywords actually do, how resumable =
functions work, or anything of the like, I can't really talk about how they=
 impact error handling with regard to optional/expected.<br><br>I'll take s=
ome time in the future to learn more about it before commenting further.<br=
></div>

<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 />

------=_Part_1122_2125293710.1432944297533--
------=_Part_1121_243278793.1432944297532--

.


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

Le 30/05/2015 02:04, Nicol Bolas a =C3=A9crit :
> Er, it seems clear that I don't really understand the resumable functions
> proposal sufficiently well to discuss it intelligently. I assumed that
> `await`ing on a function meant that you were calling a coroutine or
> something (regardless of whether it's synchronous or asynchronous).
>
> Since I don't understand what the keywords actually do, how resumable
> functions work, or anything of the like, I can't really talk about how th=
ey
> impact error handling with regard to optional/expected.
>
> I'll take some time in the future to learn more about it before commentin=
g
> further.
>
Hi Nicol,

I come back to this old thread in case you are interested in completing=20
the report in order to sent it to the standard committee.
We could try to see with Gor how the await operator helps in this use=20
case (I'm sure he will be interested).

Vicente

BTW, Have you update the report with the feedback you got?




--=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/.

--------------070301050303060903010002
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 30/05/2015 02:04, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:380d71df-3d50-4b59-b6fb-cd742017c53d@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">Er, it seems clear that I don't really understand the =
resumable functions=20
proposal sufficiently well to discuss it intelligently. I assumed that=20
`await`ing on a function meant that you were calling a coroutine or=20
something (regardless of whether it's synchronous or asynchronous).

Since I don't understand what the keywords actually do, how resumable=20
functions work, or anything of the like, I can't really talk about how they=
=20
impact error handling with regard to optional/expected.

I'll take some time in the future to learn more about it before commenting=
=20
further.

</pre>
    </blockquote>
    <font size=3D"+1">Hi Nicol,<br>
      <br>
      I come back to this old thread in case you are interested in
      completing the report in order to sent it to the standard
      committee.<br>
      We could try to see with Gor how the await operator helps in this
      use case (I'm sure he will be interested).<br>
      <br>
      Vicente<br>
      <br>
      BTW, Have you update the report with the feedback you got?<br>
      <br>
      <br>
      <br>
      <br>
    </font>
  </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 />

--------------070301050303060903010002--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Nov 2015 11:27:45 -0800 (PST)
Raw View
------=_Part_7861_1197890236.1447270065651
Content-Type: multipart/alternative;
 boundary="----=_Part_7862_2065249157.1447270065652"

------=_Part_7862_2065249157.1447270065652
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, November 11, 2015 at 1:39:13 PM UTC-5, Vicente J. Botet=20
Escriba wrote:
>
> Le 30/05/2015 02:04, Nicol Bolas a =C3=A9crit :
>
> Er, it seems clear that I don't really understand the resumable functions=
=20
> proposal sufficiently well to discuss it intelligently. I assumed that=20
> `await`ing on a function meant that you were calling a coroutine or=20
> something (regardless of whether it's synchronous or asynchronous).
>
> Since I don't understand what the keywords actually do, how resumable=20
> functions work, or anything of the like, I can't really talk about how th=
ey=20
> impact error handling with regard to optional/expected.
>
> I'll take some time in the future to learn more about it before commentin=
g=20
> further.
>
>
> Hi Nicol,
>
> I come back to this old thread in case you are interested in completing=
=20
> the report in order to sent it to the standard committee.
> We could try to see with Gor how the await operator helps in this use cas=
e=20
> (I'm sure he will be interested).
>
> Vicente
>
> BTW, Have you update the report with the feedback you got?
>

I haven't updated the report yet, but I am more conversant with resumable=
=20
functions (P0057) than I was 6 months ago.

Even so, I remain somewhat unclear on exactly how `await` would work with=
=20
an expected type, or what the consequences are.

I get that the general idea is that `expected` would have the various=20
awaitable machinery that `await <expr>` requires. So `operator await` can=
=20
be called on `expected` types. And the resulting temporary object will have=
=20
`await_ready`, `await_suspend`, and `await_resume`.

That's where I start to get foggy as to how this helps. As it has been=20
described to me, the idea with `await <expected>` is that, if the expected=
=20
object has an error, it will return from the current function and propagate=
=20
the error to its caller.

It seems like this happens by having `await_ready` return false, which=20
means that `await_suspend` will be called (presumably storing the error=20
code somewhere), followed by hitting the `suspend-resume-point`. That will=
=20
return control to the caller, and I'll assume that various resumable=20
function machinery will cause the coroutine return value to pick up the=20
error code via some mechanism.

My question is this: what happens to the current function? After all, the=
=20
current function is not yet *destroyed*; it is only suspended. When does=20
its call stack get cleaned up? Is that something that `await_suspend` does,=
=20
even though we're about to hit the `suspend-resume-point`? Does it happen=
=20
before the calling function gets to continue its execution?

I haven't seen an actual implementation of the various machinery (promise=
=20
type & awaitable), so it's hard for me to understand the details of how=20
this is supposed to work.

Another issue is the question of what this makes the function become. By=20
using `await` in this way, the function becomes a coroutine. And that seems=
=20
to create a degree of baggage. It may lead to an unwanted memory allocation=
=20
(I'm still not sure when it gets destroyed, but however it happens, I=20
suspect that this would be easy for compilers to optimize out).

It also seems to lead to some unavoidable stack overhead: the creation of=
=20
an internal `promise_type` object. There may also be a bit of added=20
overhead when returning a value, as that has to go through the promise=20
object which assembles the return value. And there's nothing you can do=20
about it even if you never get an error, unlike exceptions which can be=20
implemented in a zero-overhead way until one gets thrown.

One other thing. With all of this coroutine machinery in place, the promise=
=20
type and return value, would it be possible for such a coroutine to `await`=
=20
on things that aren't `expected` values? That is, can you have a coroutine=
=20
that `await`s on a `future`, then `await`s on an `expected`? I guess not,=
=20
since a function can only return one kind of value, and the behavior of the=
=20
coroutine for the caller is based entirely on that return type.

Or can you add special machinery to `future` and/or `generator` that can=20
handle a function that `await`s on an `expected`?

I just don't know enough about the issues here, so I can't effectively=20
assess them.

--=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/.

------=_Part_7862_2065249157.1447270065652
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, November 11, 2015 at 1:39:13 PM UTC-5, Vicente J. Botet Escri=
ba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 30/05/2015 02:04, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <pre>Er, it seems clear that I don&#39;t really understand the resuma=
ble functions=20
proposal sufficiently well to discuss it intelligently. I assumed that=20
`await`ing on a function meant that you were calling a coroutine or=20
something (regardless of whether it&#39;s synchronous or asynchronous).

Since I don&#39;t understand what the keywords actually do, how resumable=
=20
functions work, or anything of the like, I can&#39;t really talk about how =
they=20
impact error handling with regard to optional/expected.

I&#39;ll take some time in the future to learn more about it before comment=
ing=20
further.

</pre>
    </blockquote>
    <font size=3D"+1">Hi Nicol,<br>
      <br>
      I come back to this old thread in case you are interested in
      completing the report in order to sent it to the standard
      committee.<br>
      We could try to see with Gor how the await operator helps in this
      use case (I&#39;m sure he will be interested).<br>
      <br>
      Vicente<br>
      <br>
      BTW, Have you update the report with the feedback you got?<br></font>=
</div></blockquote><div><br>I haven&#39;t updated the report yet, but I am =
more conversant with resumable functions (P0057) than I was 6 months ago.<b=
r><br>Even so, I remain somewhat unclear on exactly how `await` would work =
with an expected type, or what the consequences are.<br><br>I get that the =
general idea is that `expected` would have the various awaitable machinery =
that `await &lt;expr&gt;` requires. So `operator await` can be called on `e=
xpected` types. And the resulting temporary object will have `await_ready`,=
 `await_suspend`, and `await_resume`.<br><br>That&#39;s where I start to ge=
t foggy as to how this helps. As it has been described to me, the idea with=
 `await &lt;expected&gt;` is that, if the expected object has an error, it =
will return from the current function and propagate the error to its caller=
..<br><br>It seems like this happens by having `await_ready` return false, w=
hich means that `await_suspend` will be called (presumably storing the erro=
r code somewhere), followed by hitting the `suspend-resume-point`. That wil=
l return control to the caller, and I&#39;ll assume that various resumable =
function machinery will cause the coroutine return value to pick up the err=
or code via some mechanism.<br><br>My question is this: what happens to the=
 current function? After all, the current function is not yet <i>destroyed<=
/i>; it is only suspended. When does its call stack get cleaned up? Is that=
 something that `await_suspend` does, even though we&#39;re about to hit th=
e `suspend-resume-point`? Does it happen before the calling function gets t=
o continue its execution?<br><br>I haven&#39;t seen an actual implementatio=
n of the various machinery (promise type &amp; awaitable), so it&#39;s hard=
 for me to understand the details of how this is supposed to work.<br><br>A=
nother issue is the question of what this makes the function become. By usi=
ng `await` in this way, the function becomes a coroutine. And that seems to=
 create a degree of baggage. It may lead to an unwanted memory allocation (=
I&#39;m still not sure when it gets destroyed, but however it happens, I su=
spect that this would be easy for compilers to optimize out).<br><br>It als=
o seems to lead to some unavoidable stack overhead: the creation of an inte=
rnal `promise_type` object. There may also be a bit of added overhead when =
returning a value, as that has to go through the promise object which assem=
bles the return value. And there&#39;s nothing you can do about it even if =
you never get an error, unlike exceptions which can be implemented in a zer=
o-overhead way until one gets thrown.<br><br>One other thing. With all of t=
his coroutine machinery in place, the promise type and return value, would =
it be possible for such a coroutine to `await` on things that aren&#39;t `e=
xpected` values? That is, can you have a coroutine that `await`s on a `futu=
re`, then `await`s on an `expected`? I guess not, since a function can only=
 return one kind of value, and the behavior of the coroutine for the caller=
 is based entirely on that return type.<br><br>Or can you add special machi=
nery to `future` and/or `generator` that can handle a function that `await`=
s on an `expected`?<br><br>I just don&#39;t know enough about the issues he=
re, so I can&#39;t effectively assess them.<br></div>

<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 />

------=_Part_7862_2065249157.1447270065652--
------=_Part_7861_1197890236.1447270065651--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 11 Nov 2015 21:58:18 +0100
Raw View
Le 11/11/2015 20:27, Nicol Bolas a =C3=A9crit :
> On Wednesday, November 11, 2015 at 1:39:13 PM UTC-5, Vicente J. Botet
> Escriba wrote:
>> Le 30/05/2015 02:04, Nicol Bolas a =C3=A9crit :
>>
>> Er, it seems clear that I don't really understand the resumable function=
s
>> proposal sufficiently well to discuss it intelligently. I assumed that
>> `await`ing on a function meant that you were calling a coroutine or
>> something (regardless of whether it's synchronous or asynchronous).
>>
>> Since I don't understand what the keywords actually do, how resumable
>> functions work, or anything of the like, I can't really talk about how t=
hey
>> impact error handling with regard to optional/expected.
>>
>> I'll take some time in the future to learn more about it before commenti=
ng
>> further.
>>
>>
>> Hi Nicol,
>>
>> I come back to this old thread in case you are interested in completing
>> the report in order to sent it to the standard committee.
>> We could try to see with Gor how the await operator helps in this use ca=
se
>> (I'm sure he will be interested).
>>
>> Vicente
>>
>> BTW, Have you update the report with the feedback you got?
>>
> I haven't updated the report yet, but I am more conversant with resumable
> functions (P0057) than I was 6 months ago.
>
> Even so, I remain somewhat unclear on exactly how `await` would work with
> an expected type, or what the consequences are.
>
> I get that the general idea is that `expected` would have the various
> awaitable machinery that `await <expr>` requires. So `operator await` can
> be called on `expected` types. And the resulting temporary object will ha=
ve
> `await_ready`, `await_suspend`, and `await_resume`.
>
> That's where I start to get foggy as to how this helps. As it has been
> described to me, the idea with `await <expected>` is that, if the expecte=
d
> object has an error, it will return from the current function and propaga=
te
> the error to its caller.
Right. This is as if we called a function that throw an exception and=20
the exception is propagated to the caller. This is the magic thing that=20
makes await useful for expected<T>. A single keyword used to report the=20
errors transparently :)
> It seems like this happens by having `await_ready` return false, which
> means that `await_suspend` will be called (presumably storing the error
> code somewhere), followed by hitting the `suspend-resume-point`. That wil=
l
> return control to the caller, and I'll assume that various resumable
> function machinery will cause the coroutine return value to pick up the
> error code via some mechanism.
I don' master the last proposal, but the expected mapping should not=20
suspend as the value is already ready.
>
> My question is this: what happens to the current function? After all, the
> current function is not yet *destroyed*; it is only suspended. When does
> its call stack get cleaned up? Is that something that `await_suspend` doe=
s,
> even though we're about to hit the `suspend-resume-point`? Does it happen
> before the calling function gets to continue its execution?
As I said the coroutine would not be suspended. We need the help of Gor=20
to show the exact mapping.
>
> I haven't seen an actual implementation of the various machinery (promise
> type & awaitable), so it's hard for me to understand the details of how
> this is supposed to work.
>
> Another issue is the question of what this makes the function become. By
> using `await` in this way, the function becomes a coroutine.
Yes, however I don't think we should call it a coroutine as it never=20
suspend. Anyway, the proposal call them coroutines.
> And that seems
> to create a degree of baggage. It may lead to an unwanted memory allocati=
on
> (I'm still not sure when it gets destroyed, but however it happens, I
> suspect that this would be easy for compilers to optimize out).
I don't see the need to allocate any additional memory.
>
> It also seems to lead to some unavoidable stack overhead: the creation of
> an internal `promise_type` object. There may also be a bit of added
> overhead when returning a value, as that has to go through the promise
> object which assembles the return value. And there's nothing you can do
> about it even if you never get an error, unlike exceptions which can be
> implemented in a zero-overhead way until one gets thrown.
You know surely more than me. I believe that we can not discuss it in=20
more detail until we have a specific mapping.
>
> One other thing. With all of this coroutine machinery in place, the promi=
se
> type and return value, would it be possible for such a coroutine to `awai=
t`
> on things that aren't `expected` values?
I don't think this is possible. The opposite should be possible, for a=20
function returning a future to await on an expected, but I don't know if=20
the current proposal allows it.
> That is, can you have a coroutine
> that `await`s on a `future`, then `await`s on an `expected`? I guess not,
> since a function can only return one kind of value, and the behavior of t=
he
> coroutine for the caller is based entirely on that return type.
Right.
>
> Or can you add special machinery to `future` and/or `generator` that can
> handle a function that `await`s on an `expected`?
I will create another thread about the possible interactions between=20
future<T> and expected<T>. I would like that future<T> has a ready state=20
represented as expected<T>. Maybe this would open the way to some kind=20
of interaction.
>
> I just don't know enough about the issues here, so I can't effectively
> assess them.
>
Gor, do you have coroutine_traits specialization for expected<T>, so=20
that we can see if there is any overhead?

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/.

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 11 Nov 2015 14:05:02 -0800 (PST)
Raw View
------=_Part_10099_1572927060.1447279502606
Content-Type: multipart/alternative;
 boundary="----=_Part_10100_825262085.1447279502608"

------=_Part_10100_825262085.1447279502608
Content-Type: text/plain; charset=UTF-8

Please see attached file.
Here are a usage example:

expected<int> ok() { return 42; }


expected<int> bad() { return{ error, 5 }; }


expected<int> f() {

  auto x = await ok();

  auto y = await ok();

  return x + y;

}


expected<int> g() {

  auto x = await ok(); // unpacks result of OK into x

  auto y = await bad(); // will propagate the error as the result of g()

  return x + y;

}

Coroutine promise for the function returning expected<T> is:

namespace std { namespace experimental {

  template <typename T, typename... Whatever>

  struct coroutine_traits<expected<T>, Whatever...> {

    struct promise_type {

      expected<T>* r;
      void return_value(T val) { r->val = val; r->err = 0; }

      void return_value(error_t, int err) { r->err = err; }

      expected<T> get_return_object(expected<T>* x) { r = x; return expected
<T>{}; }

   };

  };

} }


Note, this works with private version of compiler with a few tweaks that
are not part of P0057R0/R1.

Namely, I made initial_suspend/final_suspend optional. If coroutine_promise
does not have those, coroutine is not meant to be suspended.
Second tweak, (not sure if I like it, I am still experimenting), if
coroutine is not suspendable, I pass a pointer to a value being returned to
a get_return_object, this allows to deal with values like expected that are
not split into consuming part (future) and the promise. I can also
implement it without changing the get_return_object at all, but, that will
require clarification in wording that in non-suspending coroutines
get_return_object is called after user authored body is completed, as
opposed to before user authored body is entered as it is traditional
coroutines.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_10100_825262085.1447279502608
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Please see attached file. </div><div>Here are a usage=
 example:</div><div><br></div><p><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">expected&lt;</font></font><font color=3D"#0000f=
f" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></=
font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&gt; ok() { </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font></font></font><font =
face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> 42; }</fon=
t></font></p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><fon=
t face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; bad() { <=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">return</font></font></font><font face=3D"Consolas" si=
ze=3D"2"><font face=3D"Consolas" size=3D"2">{ error, 5 }; }</font></font></=
p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; f() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><p><br></p></font></font><div><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; g() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok(); // unpacks result of O=
K into x</font></font></p><div><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> bad(); // will propagate the=
 error as the result of g()</font></font></p><div><font face=3D"Consolas" s=
ize=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><div><br></div><div>Coroutine promise for the functi=
on returning expected&lt;T&gt; is:</div><div><br></div><div><p><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">na=
mespace</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2"> std { </font></font><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2"> experimental {</font></font></p><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 template</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;<=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">typename</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Cons=
olas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</fo=
nt></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2">, </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">typename</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">... </font></=
font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2=
b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consola=
s" size=3D"2">Whatever</font></font></font><font face=3D"Consolas" size=3D"=
2"><font face=3D"Consolas" size=3D"2">&gt;</font></font></p><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0struct</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fon=
t></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">coroutine_traits</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D=
"2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;, </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2">Whatever</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">...&gt; {</font></font><=
/p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0 struct</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font =
color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2">promise_type</font></font></font><font face=3D"Con=
solas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {</font></font></p><f=
ont face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt;* r;</font></font></=
p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font=
 color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D=
"2">val</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2">) { r-&gt;val =3D </font></font><font color=3D"#80=
8080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">val</font=
></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" s=
ize=3D"2">; r-&gt;err =3D 0; }</font></font><font face=3D"Consolas" size=3D=
"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font>=
</font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
"> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2">error_t</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></fo=
nt><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#000=
0ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas"=
 size=3D"2">int</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#808080" face=
=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"=
2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
) { r-&gt;err =3D </font></font><font color=3D"#808080" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">; }</font></fo=
nt></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; get_return_object(<=
/font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font col=
or=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D=
"Consolas" size=3D"2">expected</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">&gt;* </font></font><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font col=
or=3D"#808080" face=3D"Consolas" size=3D"2">x</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">) { r =3D </fo=
nt></font><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"C=
onsolas" size=3D"2">x</font></font></font><font face=3D"Consolas" size=3D"2=
"><font face=3D"Consolas" size=3D"2">; </font></font><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font>=
</font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" si=
ze=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2=
"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2">expected</font></font></font><font face=3D=
"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font>=
<font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af=
" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" si=
ze=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">&gt;{}; }</font></font></p><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">
<p>=C2=A0=C2=A0 };</p>
<p>=C2=A0=C2=A0};</p>
<p>} }</p><p><br></p><p>Note, this works with private version of compiler w=
ith a few tweaks that are not part of P0057R0/R1.</p><div><br></div><div>Na=
mely, I made initial_suspend/final_suspend optional. If coroutine_promise d=
oes not have those, coroutine is not meant to be suspended.</div><div>Secon=
d tweak, (not sure if I like it, I am still experimenting), if coroutine is=
 not suspendable, I pass a pointer to a value being returned to a get_retur=
n_object, this allows to deal with values like expected that are not split =
into consuming part (future) and the promise. I can also implement it witho=
ut changing the get_return_object at all, but, that will require clarificat=
ion in wording that in non-suspending coroutines get_return_object is calle=
d after user authored body is completed, as opposed to before user authored=
 body is entered as it is traditional coroutines.</div></font></font></div>=
</font></font></div>

<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 />

------=_Part_10100_825262085.1447279502608--
------=_Part_10099_1572927060.1447279502606--

.


Author: Shahms King <shahms.king@gmail.com>
Date: Wed, 11 Nov 2015 22:11:46 +0000
Raw View
--001a113ddbbc5de1a405244b1d73
Content-Type: text/plain; charset=UTF-8

Without await_transform() how does this deal with awaiting on a suspending
awaitable from within a non-suspending promise?  At least with the most
recent wording I've seen, the above is unsafe as it allows:

expected<T, E> unsafe() {
  auto value = await another_expected();  // Fine.
  auto next = await returns_a_future();  // Uh-oh, we've returned to our
caller without a value.
  return T{};
}

--Shahms



On Wed, Nov 11, 2015 at 2:05 PM Gor Nishanov <gornishanov@gmail.com> wrote:

> Please see attached file.
> Here are a usage example:
>
> expected<int> ok() { return 42; }
>
>
> expected<int> bad() { return{ error, 5 }; }
>
>
> expected<int> f() {
>
>   auto x = await ok();
>
>   auto y = await ok();
>
>   return x + y;
>
> }
>
>
> expected<int> g() {
>
>   auto x = await ok(); // unpacks result of OK into x
>
>   auto y = await bad(); // will propagate the error as the result of g()
>
>   return x + y;
>
> }
>
> Coroutine promise for the function returning expected<T> is:
>
> namespace std { namespace experimental {
>
>   template <typename T, typename... Whatever>
>
>   struct coroutine_traits<expected<T>, Whatever...> {
>
>     struct promise_type {
>
>       expected<T>* r;
>       void return_value(T val) { r->val = val; r->err = 0; }
>
>       void return_value(error_t, int err) { r->err = err; }
>
>       expected<T> get_return_object(expected<T>* x) { r = x; return
> expected<T>{}; }
>
>    };
>
>   };
>
> } }
>
>
> Note, this works with private version of compiler with a few tweaks that
> are not part of P0057R0/R1.
>
> Namely, I made initial_suspend/final_suspend optional. If
> coroutine_promise does not have those, coroutine is not meant to be
> suspended.
> Second tweak, (not sure if I like it, I am still experimenting), if
> coroutine is not suspendable, I pass a pointer to a value being returned to
> a get_return_object, this allows to deal with values like expected that are
> not split into consuming part (future) and the promise. I can also
> implement it without changing the get_return_object at all, but, that will
> require clarification in wording that in non-suspending coroutines
> get_return_object is called after user authored body is completed, as
> opposed to before user authored body is entered as it is traditional
> coroutines.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a113ddbbc5de1a405244b1d73
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Without await_transform() how does this deal with awaiting=
 on a suspending awaitable from within a non-suspending promise?=C2=A0 At l=
east with the most recent wording I&#39;ve seen, the above is unsafe as it =
allows:<div><br></div><div>expected&lt;T, E&gt; unsafe() {</div><div>=C2=A0=
 auto value =3D await another_expected(); =C2=A0// Fine.</div><div>=C2=A0 a=
uto next =3D await returns_a_future(); =C2=A0// Uh-oh, we&#39;ve returned t=
o our caller without a value.</div><div>=C2=A0 return T{};</div><div>}</div=
><div><br></div><div>--Shahms<br><div><br></div><div><br></div></div></div>=
<br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Nov 11, 2015 at 2:0=
5 PM Gor Nishanov &lt;<a href=3D"mailto:gornishanov@gmail.com">gornishanov@=
gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>Please see attached file. </div><div>Here are a usage example=
:</div><div><br></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"C=
onsolas" size=3D"2">expected&lt;</font></font><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
&gt; ok() { </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">return</font></font></font><font face=3D=
"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> 42; }</font></fon=
t></p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; bad() { <=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">return</font></font></font><font face=3D"Consolas" si=
ze=3D"2"><font face=3D"Consolas" size=3D"2">{ error, 5 }; }</font></font></=
p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; f() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><p><br></p></font></font><div><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; g() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok(); // unpacks result of O=
K into x</font></font></p><div><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> bad(); // will propagate the=
 error as the result of g()</font></font></p><div><font face=3D"Consolas" s=
ize=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><div><br></div><div>Coroutine promise for the functi=
on returning expected&lt;T&gt; is:</div><div><br></div><div><p><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">na=
mespace</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2"> std { </font></font><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2"> experimental {</font></font></p><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 template</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;<=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">typename</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Cons=
olas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</fo=
nt></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2">, </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">typename</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">... </font></=
font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2=
b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consola=
s" size=3D"2">Whatever</font></font></font><font face=3D"Consolas" size=3D"=
2"><font face=3D"Consolas" size=3D"2">&gt;</font></font></p><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0struct</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fon=
t></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">coroutine_traits</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D=
"2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;, </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2">Whatever</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">...&gt; {</font></font><=
/p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0 struct</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font =
color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2">promise_type</font></font></font><font face=3D"Con=
solas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {</font></font></p><f=
ont face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt;* r;</font></font></=
p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font=
 color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D=
"2">val</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2">) { r-&gt;val =3D </font></font><font color=3D"#80=
8080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">val</font=
></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" s=
ize=3D"2">; r-&gt;err =3D 0; }</font></font><font face=3D"Consolas" size=3D=
"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font>=
</font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
"> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2">error_t</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></fo=
nt><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#000=
0ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas"=
 size=3D"2">int</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#808080" face=
=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"=
2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
) { r-&gt;err =3D </font></font><font color=3D"#808080" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">; }</font></fo=
nt></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; get_return_object(<=
/font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font col=
or=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D=
"Consolas" size=3D"2">expected</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">&gt;* </font></font><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font col=
or=3D"#808080" face=3D"Consolas" size=3D"2">x</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">) { r =3D </fo=
nt></font><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"C=
onsolas" size=3D"2">x</font></font></font><font face=3D"Consolas" size=3D"2=
"><font face=3D"Consolas" size=3D"2">; </font></font><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font>=
</font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" si=
ze=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2=
"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2">expected</font></font></font><font face=3D=
"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font>=
<font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af=
" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" si=
ze=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">&gt;{}; }</font></font></p><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">
<p>=C2=A0=C2=A0 };</p>
<p>=C2=A0=C2=A0};</p>
<p>} }</p><p><br></p><p>Note, this works with private version of compiler w=
ith a few tweaks that are not part of P0057R0/R1.</p><div><br></div><div>Na=
mely, I made initial_suspend/final_suspend optional. If coroutine_promise d=
oes not have those, coroutine is not meant to be suspended.</div><div>Secon=
d tweak, (not sure if I like it, I am still experimenting), if coroutine is=
 not suspendable, I pass a pointer to a value being returned to a get_retur=
n_object, this allows to deal with values like expected that are not split =
into consuming part (future) and the promise. I can also implement it witho=
ut changing the get_return_object at all, but, that will require clarificat=
ion in wording that in non-suspending coroutines get_return_object is calle=
d after user authored body is completed, as opposed to before user authored=
 body is entered as it is traditional coroutines.</div></font></font></div>=
</font></font></div>

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</blockquote></div>

<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 />

--001a113ddbbc5de1a405244b1d73--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 11 Nov 2015 14:25:46 -0800 (PST)
Raw View
------=_Part_450_618567857.1447280746314
Content-Type: multipart/alternative;
 boundary="----=_Part_451_1820363327.1447280746317"

------=_Part_451_1820363327.1447280746317
Content-Type: text/plain; charset=UTF-8

Yep. As soon as I add await_transform (probably later this week), you will
be able to ban things like future<T> from coroutines returning expected<T>.
It will look like this:

namespace std { namespace experimental {

   template <typename T> struct is_suspendable : true_type {}; // awaiting
on anything can result in suspension

}}

Primary template states that by default we consider everything suspendable.
We will specialize for expected to say that awaitng won't result in
suspension:

namespace std { namespace experimental {

   template <typename T> struct is_suspendable<expected<T>> : false_type
{}; // but not on expected

}}

And you add the following await_transform to the promise:

template <typename Awaitable>

enable_if<is_suspendable<Awaitable>::value> await_transform(Awaitable const&)
{

  static_assert(false, "expected<T> does not support awaiting on
suspendable types");

}

Now you will get a nice compile time error if you, say, await on a future.

On Wednesday, November 11, 2015 at 2:11:58 PM UTC-8, Shahms King wrote:

> Without await_transform() how does this deal with awaiting on a suspending
> awaitable from within a non-suspending promise?  At least with the most
> recent wording I've seen, the above is unsafe as it allows:
>
> expected<T, E> unsafe() {
>   auto value = await another_expected();  // Fine.
>   auto next = await returns_a_future();  // Uh-oh, we've returned to our
> caller without a value.
>   return T{};
> }
>
> --Shahms
>
>
>
> On Wed, Nov 11, 2015 at 2:05 PM Gor Nishanov <gorni...@gmail.com
> <javascript:>> wrote:
>
>> Please see attached file.
>> Here are a usage example:
>>
>> expected<int> ok() { return 42; }
>>
>>
>> expected<int> bad() { return{ error, 5 }; }
>>
>>
>> expected<int> f() {
>>
>>   auto x = await ok();
>>
>>   auto y = await ok();
>>
>>   return x + y;
>>
>> }
>>
>>
>> expected<int> g() {
>>
>>   auto x = await ok(); // unpacks result of OK into x
>>
>>   auto y = await bad(); // will propagate the error as the result of g()
>>
>>   return x + y;
>>
>> }
>>
>> Coroutine promise for the function returning expected<T> is:
>>
>> namespace std { namespace experimental {
>>
>>   template <typename T, typename... Whatever>
>>
>>   struct coroutine_traits<expected<T>, Whatever...> {
>>
>>     struct promise_type {
>>
>>       expected<T>* r;
>>       void return_value(T val) { r->val = val; r->err = 0; }
>>
>>       void return_value(error_t, int err) { r->err = err; }
>>
>>       expected<T> get_return_object(expected<T>* x) { r = x; return
>> expected<T>{}; }
>>
>>    };
>>
>>   };
>>
>> } }
>>
>>
>> Note, this works with private version of compiler with a few tweaks that
>> are not part of P0057R0/R1.
>>
>> Namely, I made initial_suspend/final_suspend optional. If
>> coroutine_promise does not have those, coroutine is not meant to be
>> suspended.
>> Second tweak, (not sure if I like it, I am still experimenting), if
>> coroutine is not suspendable, I pass a pointer to a value being returned to
>> a get_return_object, this allows to deal with values like expected that are
>> not split into consuming part (future) and the promise. I can also
>> implement it without changing the get_return_object at all, but, that will
>> require clarification in wording that in non-suspending coroutines
>> get_return_object is called after user authored body is completed, as
>> opposed to before user authored body is entered as it is traditional
>> coroutines.
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_451_1820363327.1447280746317
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Yep. As soon as I add await_transform (probably later=
 this week), you will be able to ban things like future&lt;T&gt; from corou=
tines returning expected&lt;T&gt;.</div><div>It will look like this:</div><=
div><br></div><div><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">=
<font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2">namespace</font></font></font><font face=3D"=
Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> std { </font></fon=
t><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000=
ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2">namespace</font></font></font><font face=3D"Consolas" size=3D"2"=
><font face=3D"Consolas" size=3D"2"> experimental {</font></font></p><font =
face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0 template</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
 &lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">typename</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"C=
onsolas" size=3D"2">&gt; </font></font><font color=3D"#0000ff" face=3D"Cons=
olas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2">struct</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2"> : </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">true_type</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2"> {}; </font></font><font color=3D"#008000" face=
=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"=
2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">// awaiting on anyt=
hing can result in suspension</font></font></font></p><font color=3D"#00800=
0" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">
</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Conso=
las" size=3D"2"><p>}}</p></font></font></div><div><br></div><div>Primary te=
mplate states that by default we consider everything suspendable. We will s=
pecialize for expected to say that=C2=A0awaitng=C2=A0won&#39;t result in su=
spension:</div><div><br></div><div><p><font color=3D"#0000ff" face=3D"Conso=
las" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font =
color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></font></fon=
t><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> st=
d { </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2">namespace</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> experimental {</font><=
/font></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0 template</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
 &lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">typename</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"C=
onsolas" size=3D"2">&gt; </font></font><font color=3D"#0000ff" face=3D"Cons=
olas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2">struct</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font c=
olor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font fa=
ce=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;&gt; : </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"=
><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91a=
f" face=3D"Consolas" size=3D"2">false_type</font></font></font><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {}; </font></f=
ont><font color=3D"#008000" face=3D"Consolas" size=3D"2"><font color=3D"#00=
8000" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas=
" size=3D"2">// but not on expected</font></font></font></p><font color=3D"=
#008000" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Conso=
las" size=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">
</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Conso=
las" size=3D"2"><p>}}</p></font></font></div><div><br></div><div><div>And y=
ou add the following await_transform to the promise:</div><div><br></div></=
div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">   </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">template</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;</font></font><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2">typename</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">Awaitable</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&gt;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2">enable_if</font></font></font><fo=
nt face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font c=
olor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">Awaitable</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&gt;::value&gt; await_transform(</font></font><=
font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af"=
 face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2">Awaitable</font></font></font><font face=3D"Consolas" size=3D"2"><f=
ont face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">const</font></font=
></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"=
2">&amp;) {</font></font></p><div><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 static_assert</font></font=
></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"=
2">(</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2">false</font></font></font><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></font><font color=
=3D"#a31515" face=3D"Consolas" size=3D"2"><font color=3D"#a31515" face=3D"C=
onsolas" size=3D"2"><font color=3D"#a31515" face=3D"Consolas" size=3D"2">&q=
uot;expected&lt;T&gt; does not support awaiting on suspendable types&quot;<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">);</font></font></p><div><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>   }</p></font></font><div><br></div><div>Now you will ge=
t a nice compile time error if you, say, await on a future.</div><div><br>O=
n Wednesday, November 11, 2015 at 2:11:58 PM UTC-8, Shahms King wrote:</div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Without awai=
t_transform() how does this deal with awaiting on a suspending awaitable fr=
om within a non-suspending promise?=C2=A0 At least with the most recent wor=
ding I&#39;ve seen, the above is unsafe as it allows:<div><br></div><div>ex=
pected&lt;T, E&gt; unsafe() {</div><div>=C2=A0 auto value =3D await another=
_expected(); =C2=A0// Fine.</div><div>=C2=A0 auto next =3D await returns_a_=
future(); =C2=A0// Uh-oh, we&#39;ve returned to our caller without a value.=
</div><div>=C2=A0 return T{};</div><div>}</div><div><br></div><div>--Shahms=
<br><div><br></div><div><br></div></div></div><br><div class=3D"gmail_quote=
"><div dir=3D"ltr">On Wed, Nov 11, 2015 at 2:05 PM Gor Nishanov &lt;<a onmo=
usedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.=
href=3D&#39;javascript:&#39;;return true;" href=3D"javascript:" target=3D"_=
blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"RqIEGkBKFwAJ">gorni...@gma=
il.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>Please see attached file. </div><div>Here are a usage example:</di=
v><div><br></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">expected&lt;</font></font><font color=3D"#0000ff" face=3D"Co=
nsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; o=
k() { </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">return</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2"> 42; }</font></font></p>=
<p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=3D"Con=
solas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; bad() { <=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">return</font></font></font><font face=3D"Consolas" si=
ze=3D"2"><font face=3D"Consolas" size=3D"2">{ error, 5 }; }</font></font></=
p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; f() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><p><br></p></font></font><div><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; g() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok(); // unpacks result of O=
K into x</font></font></p><div><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> bad(); // will propagate the=
 error as the result of g()</font></font></p><div><font face=3D"Consolas" s=
ize=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><div><br></div><div>Coroutine promise for the functi=
on returning expected&lt;T&gt; is:</div><div><br></div><div><p><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">na=
mespace</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2"> std { </font></font><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2"> experimental {</font></font></p><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 template</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;<=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">typename</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Cons=
olas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</fo=
nt></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2">, </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">typename</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">... </font></=
font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2=
b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consola=
s" size=3D"2">Whatever</font></font></font><font face=3D"Consolas" size=3D"=
2"><font face=3D"Consolas" size=3D"2">&gt;</font></font></p><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0struct</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fon=
t></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">coroutine_traits</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D=
"2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;, </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2">Whatever</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">...&gt; {</font></font><=
/p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0 struct</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font =
color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2">promise_type</font></font></font><font face=3D"Con=
solas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {</font></font></p><f=
ont face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt;* r;</font></font></=
p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font=
 color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D=
"2">val</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2">) { r-&gt;val =3D </font></font><font color=3D"#80=
8080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">val</font=
></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" s=
ize=3D"2">; r-&gt;err =3D 0; }</font></font><font face=3D"Consolas" size=3D=
"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font>=
</font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
"> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2">error_t</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></fo=
nt><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#000=
0ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas"=
 size=3D"2">int</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#808080" face=
=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"=
2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
) { r-&gt;err =3D </font></font><font color=3D"#808080" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">; }</font></fo=
nt></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; get_return_object(<=
/font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font col=
or=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D=
"Consolas" size=3D"2">expected</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">&gt;* </font></font><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font col=
or=3D"#808080" face=3D"Consolas" size=3D"2">x</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">) { r =3D </fo=
nt></font><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"C=
onsolas" size=3D"2">x</font></font></font><font face=3D"Consolas" size=3D"2=
"><font face=3D"Consolas" size=3D"2">; </font></font><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font>=
</font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" si=
ze=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2=
"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2">expected</font></font></font><font face=3D=
"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font>=
<font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af=
" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" si=
ze=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">&gt;{}; }</font></font></p><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">
<p>=C2=A0=C2=A0 };</p>
<p>=C2=A0=C2=A0};</p>
<p>} }</p><p><br></p><p>Note, this works with private version of compiler w=
ith a few tweaks that are not part of P0057R0/R1.</p><div><br></div><div>Na=
mely, I made initial_suspend/final_suspend optional. If coroutine_promise d=
oes not have those, coroutine is not meant to be suspended.</div><div>Secon=
d tweak, (not sure if I like it, I am still experimenting), if coroutine is=
 not suspendable, I pass a pointer to a value being returned to a get_retur=
n_object, this allows to deal with values like expected that are not split =
into consuming part (future) and the promise. I can also implement it witho=
ut changing the get_return_object at all, but, that will require clarificat=
ion in wording that in non-suspending coroutines get_return_object is calle=
d after user authored body is completed, as opposed to before user authored=
 body is entered as it is traditional coroutines.</div></font></font></div>=
</font></font></div>

<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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"RqIEGkBKFwA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"RqIEGkBKFwAJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D&#39;http://groups.google=
..com/a/isocpp.org/group/std-proposals/&#39;;return true;" onclick=3D"this.h=
ref=3D&#39;http://groups.google.com/a/isocpp.org/group/std-proposals/&#39;;=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</blockquote></div>
</blockquote></div>

<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 />

------=_Part_451_1820363327.1447280746317--
------=_Part_450_618567857.1447280746314--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Nov 2015 14:27:10 -0800 (PST)
Raw View
------=_Part_1066_1412456901.1447280830696
Content-Type: multipart/alternative;
 boundary="----=_Part_1067_55029534.1447280830697"

------=_Part_1067_55029534.1447280830697
Content-Type: text/plain; charset=UTF-8

On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishanov wrote:
>
> Please see attached file
>

I don't see an attachment in your post. But I do see the code you put into
the post.

One thing it's missing is the awaiter type. Or if `expected` has the
appropriate interface, I don't see how that gets implemented. I want to see
what `await_ready`, `await_suspend` and `await_resume` do for an `expected`.

Here are a usage example:
>
> expected<int> ok() { return 42; }
>
>
> expected<int> bad() { return{ error, 5 }; }
>
>
> expected<int> f() {
>
>   auto x = await ok();
>
>   auto y = await ok();
>
>   return x + y;
>
> }
>
>
> expected<int> g() {
>
>   auto x = await ok(); // unpacks result of OK into x
>
>   auto y = await bad(); // will propagate the error as the result of g()
>
>   return x + y;
>
> }
>
> Coroutine promise for the function returning expected<T> is:
>
> namespace std { namespace experimental {
>
>   template <typename T, typename... Whatever>
>
>   struct coroutine_traits<expected<T>, Whatever...> {
>
>     struct promise_type {
>
>       expected<T>* r;
>       void return_value(T val) { r->val = val; r->err = 0; }
>
>       void return_value(error_t, int err) { r->err = err; }
>
>       expected<T> get_return_object(expected<T>* x) { r = x; return
> expected<T>{}; }
>
>    };
>
>   };
>
> } }
>
>
> Note, this works with private version of compiler with a few tweaks that
> are not part of P0057R0/R1.
>

I'd call something like this a bit more than a "tweak". You're effectively
defining a new kind of coroutine.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1067_55029534.1447280830697
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor N=
ishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div>Please see attached file</div></div></blockquote><div><br>I don&#39;t=
 see an attachment in your post. But I do see the code you put into the pos=
t.<br><br>One thing it&#39;s missing is the awaiter type. Or if `expected` =
has the appropriate interface, I don&#39;t see how that gets implemented. I=
 want to see what `await_ready`, `await_suspend` and `await_resume` do for =
an `expected`.<br><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div> </div><div>Here are a usage example:</div><div><br></d=
iv><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"=
>expected&lt;</font></font><font color=3D"#0000ff" size=3D"2" face=3D"Conso=
las"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0=
000ff" size=3D"2" face=3D"Consolas">int</font></font></font><font size=3D"2=
" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt; ok() { </font><=
/font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#=
0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2" fac=
e=3D"Consolas">return</font></font></font><font size=3D"2" face=3D"Consolas=
"><font size=3D"2" face=3D"Consolas"> 42; }</font></font></p><p><font size=
=3D"2" face=3D"Consolas"><br></font></p><div><font size=3D"2" face=3D"Conso=
las"><font size=3D"2" face=3D"Consolas">
</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font co=
lor=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=
=3D"2" face=3D"Consolas"></font></font></font></div><p><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D=
"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">expected</f=
ont></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">&lt;</font></font><font color=3D"#0000ff" size=3D"2" face=3D"=
Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">int</font></font></font><font siz=
e=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt; bad() { <=
/font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font col=
or=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D=
"2" face=3D"Consolas">return</font></font></font><font size=3D"2" face=3D"C=
onsolas"><font size=3D"2" face=3D"Consolas">{ error, 5 }; }</font></font></=
p><p><font size=3D"2" face=3D"Consolas"><br></font></p><div><font size=3D"2=
" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">

</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font co=
lor=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=
=3D"2" face=3D"Consolas"></font></font></font></div><p><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D=
"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">expected</f=
ont></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">&lt;</font></font><font color=3D"#0000ff" size=3D"2" face=3D"=
Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">int</font></font></font><font siz=
e=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt; f() {</fo=
nt></font></p><div><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 auto</font></font></font><=
font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> x =3D=
 </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font c=
olor=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas">await</font></font></font><font size=3D"2" face=3D=
"Consolas"><font size=3D"2" face=3D"Consolas"> ok();</font></font></p><div>=
<font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 auto</font></font></font><=
font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> y =3D=
 </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font c=
olor=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas">await</font></font></font><font size=3D"2" face=3D=
"Consolas"><font size=3D"2" face=3D"Consolas"> ok();</font></font></p><div>=
<font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 return</font></font></font=
><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> x +=
 y;</font></font></p><div><font size=3D"2" face=3D"Consolas"><font size=3D"=
2" face=3D"Consolas">
</font></font></div><font size=3D"2" face=3D"Consolas"><font size=3D"2" fac=
e=3D"Consolas"><p>}</p><p><br></p></font></font><div><font size=3D"2" face=
=3D"Consolas"><font size=3D"2" face=3D"Consolas">

</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font co=
lor=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=
=3D"2" face=3D"Consolas"></font></font></font></div><p><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D=
"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">expected</f=
ont></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">&lt;</font></font><font color=3D"#0000ff" size=3D"2" face=3D"=
Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">int</font></font></font><font siz=
e=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt; g() {</fo=
nt></font></p><div><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 auto</font></font></font><=
font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> x =3D=
 </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font c=
olor=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas">await</font></font></font><font size=3D"2" face=3D=
"Consolas"><font size=3D"2" face=3D"Consolas"> ok(); // unpacks result of O=
K into x</font></font></p><div><font size=3D"2" face=3D"Consolas"><font siz=
e=3D"2" face=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 auto</font></font></font><=
font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> y =3D=
 </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font c=
olor=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas">await</font></font></font><font size=3D"2" face=3D=
"Consolas"><font size=3D"2" face=3D"Consolas"> bad(); // will propagate the=
 error as the result of g()</font></font></p><div><font size=3D"2" face=3D"=
Consolas"><font size=3D"2" face=3D"Consolas">
</font></font></div><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" =
face=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D=
"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 return</font></font></font=
><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> x +=
 y;</font></font></p><div><font size=3D"2" face=3D"Consolas"><font size=3D"=
2" face=3D"Consolas">
</font></font></div><font size=3D"2" face=3D"Consolas"><font size=3D"2" fac=
e=3D"Consolas"><p>}</p><div><br></div><div>Coroutine promise for the functi=
on returning expected&lt;T&gt; is:</div><div><br></div><div><p><font color=
=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2=
" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas">na=
mespace</font></font></font><font size=3D"2" face=3D"Consolas"><font size=
=3D"2" face=3D"Consolas"> std { </font></font><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consola=
s"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas">namespace</font></f=
ont></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Cons=
olas"> experimental {</font></font></p><font size=3D"2" face=3D"Consolas"><=
font size=3D"2" face=3D"Consolas">
</font></font><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas"> </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Con=
solas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"=
#0000ff" size=3D"2" face=3D"Consolas">=C2=A0 template</font></font></font><=
font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> &lt;<=
/font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font col=
or=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D=
"2" face=3D"Consolas">typename</font></font></font><font size=3D"2" face=3D=
"Consolas"><font size=3D"2" face=3D"Consolas"> </font></font><font color=3D=
"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" f=
ace=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">T</fo=
nt></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas">, </font></font><font color=3D"#0000ff" size=3D"2" face=3D"Co=
nsolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D=
"#0000ff" size=3D"2" face=3D"Consolas">typename</font></font></font><font s=
ize=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">... </font><=
/font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#=
2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" fac=
e=3D"Consolas">Whatever</font></font></font><font size=3D"2" face=3D"Consol=
as"><font size=3D"2" face=3D"Consolas">&gt;</font></font></p><font size=3D"=
2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas"></font></font><font color=3D"#0000ff" size=3D"2" face=3D"Cons=
olas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#=
0000ff" size=3D"2" face=3D"Consolas">=C2=A0=C2=A0struct</font></font></font=
><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> </f=
ont></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=
=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2=
" face=3D"Consolas">coroutine_traits</font></font></font><font size=3D"2" f=
ace=3D"Consolas"><font size=3D"2" face=3D"Consolas">&lt;</font></font><font=
 color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" siz=
e=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consol=
as">expected</font></font></font><font size=3D"2" face=3D"Consolas"><font s=
ize=3D"2" face=3D"Consolas">&lt;</font></font><font color=3D"#2b91af" size=
=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consola=
s"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">T</font></font></fo=
nt><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&g=
t;, </font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><fon=
t color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" si=
ze=3D"2" face=3D"Consolas">Whatever</font></font></font><font size=3D"2" fa=
ce=3D"Consolas"><font size=3D"2" face=3D"Consolas">...&gt; {</font></font><=
/p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font><p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=
=3D"Consolas"></font></font><font color=3D"#0000ff" size=3D"2" face=3D"Cons=
olas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#=
0000ff" size=3D"2" face=3D"Consolas">=C2=A0=C2=A0=C2=A0 struct</font></font=
></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consola=
s"> </font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><fon=
t color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" si=
ze=3D"2" face=3D"Consolas">promise_type</font></font></font><font size=3D"2=
" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> {</font></font></p>=
<font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font><p><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font=
 color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" siz=
e=3D"2" face=3D"Consolas">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Cons=
olas">&lt;</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas=
"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas">T</font></font></font><font size=3D"2" fac=
e=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt;* r;</font></font></p=
><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">
</font></font><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font co=
lor=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=
=3D"2" face=3D"Consolas">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font><=
/font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"=
> return_value(</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Con=
solas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"=
#2b91af" size=3D"2" face=3D"Consolas">T</font></font></font><font size=3D"2=
" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"> </font></font><font=
 color=3D"#808080" size=3D"2" face=3D"Consolas"><font color=3D"#808080" siz=
e=3D"2" face=3D"Consolas"><font color=3D"#808080" size=3D"2" face=3D"Consol=
as">val</font></font></font><font size=3D"2" face=3D"Consolas"><font size=
=3D"2" face=3D"Consolas">) { r-&gt;val =3D </font></font><font color=3D"#80=
8080" size=3D"2" face=3D"Consolas"><font color=3D"#808080" size=3D"2" face=
=3D"Consolas"><font color=3D"#808080" size=3D"2" face=3D"Consolas">val</fon=
t></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D=
"Consolas">; r-&gt;err =3D 0; }</font></font><font size=3D"2" face=3D"Conso=
las"><font size=3D"2" face=3D"Consolas">
</font></font><p><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font=
 color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" siz=
e=3D"2" face=3D"Consolas">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font>=
</font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas=
"> return_value(</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Co=
nsolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D=
"#2b91af" size=3D"2" face=3D"Consolas">error_t</font></font></font><font si=
ze=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">, </font></fo=
nt><font color=3D"#0000ff" size=3D"2" face=3D"Consolas"><font color=3D"#000=
0ff" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2" face=
=3D"Consolas">int</font></font></font><font size=3D"2" face=3D"Consolas"><f=
ont size=3D"2" face=3D"Consolas"> </font></font><font color=3D"#808080" siz=
e=3D"2" face=3D"Consolas"><font color=3D"#808080" size=3D"2" face=3D"Consol=
as"><font color=3D"#808080" size=3D"2" face=3D"Consolas">err</font></font><=
/font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas"=
>) { r-&gt;err =3D </font></font><font color=3D"#808080" size=3D"2" face=3D=
"Consolas"><font color=3D"#808080" size=3D"2" face=3D"Consolas"><font color=
=3D"#808080" size=3D"2" face=3D"Consolas">err</font></font></font><font siz=
e=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">; }</font></fo=
nt></p><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas=
">
</font></font><p><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font=
 color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" siz=
e=3D"2" face=3D"Consolas">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Cons=
olas">&lt;</font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas=
"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas">T</font></font></font><font size=3D"2" fac=
e=3D"Consolas"><font size=3D"2" face=3D"Consolas">&gt; get_return_object(</=
font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font colo=
r=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"=
2" face=3D"Consolas">expected</font></font></font><font size=3D"2" face=3D"=
Consolas"><font size=3D"2" face=3D"Consolas">&lt;</font></font><font color=
=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2=
" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas">T<=
/font></font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" fac=
e=3D"Consolas">&gt;* </font></font><font color=3D"#808080" size=3D"2" face=
=3D"Consolas"><font color=3D"#808080" size=3D"2" face=3D"Consolas"><font co=
lor=3D"#808080" size=3D"2" face=3D"Consolas">x</font></font></font><font si=
ze=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">) { r =3D </f=
ont></font><font color=3D"#808080" size=3D"2" face=3D"Consolas"><font color=
=3D"#808080" size=3D"2" face=3D"Consolas"><font color=3D"#808080" size=3D"2=
" face=3D"Consolas">x</font></font></font><font size=3D"2" face=3D"Consolas=
"><font size=3D"2" face=3D"Consolas">; </font></font><font color=3D"#0000ff=
" size=3D"2" face=3D"Consolas"><font color=3D"#0000ff" size=3D"2" face=3D"C=
onsolas"><font color=3D"#0000ff" size=3D"2" face=3D"Consolas">return</font>=
</font></font><font size=3D"2" face=3D"Consolas"><font size=3D"2" face=3D"C=
onsolas"> </font></font><font color=3D"#2b91af" size=3D"2" face=3D"Consolas=
"><font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91=
af" size=3D"2" face=3D"Consolas">expected</font></font></font><font size=3D=
"2" face=3D"Consolas"><font size=3D"2" face=3D"Consolas">&lt;</font></font>=
<font color=3D"#2b91af" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af=
" size=3D"2" face=3D"Consolas"><font color=3D"#2b91af" size=3D"2" face=3D"C=
onsolas">T</font></font></font><font size=3D"2" face=3D"Consolas"><font siz=
e=3D"2" face=3D"Consolas">&gt;{}; }</font></font></p><font size=3D"2" face=
=3D"Consolas"><font size=3D"2" face=3D"Consolas">
<p>=C2=A0=C2=A0 };</p>
<p>=C2=A0=C2=A0};</p>
<p>} }</p><p><br></p><p>Note, this works with private version of compiler w=
ith a few tweaks that are not part of P0057R0/R1.</p></font></font></div></=
font></font></div></blockquote><div><br>I&#39;d call something like this a =
bit more than a &quot;tweak&quot;. You&#39;re effectively defining a new ki=
nd of coroutine.<br></div></div>

<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 />

------=_Part_1067_55029534.1447280830697--
------=_Part_1066_1412456901.1447280830696--

.


Author: Shahms King <shahms.king@gmail.com>
Date: Wed, 11 Nov 2015 22:38:53 +0000
Raw View
--089e013c5db643863d05244b7e80
Content-Type: text/plain; charset=UTF-8

That certainly was my hope when I saw the mention of await_transform() in
the "future directions".  Although the extra type_traits machinery is
awkward, I don't see any way of avoiding it without pushing the mechanism
onto the awaitable via the type of the coroutine_handle.

--Shahms

On Wed, Nov 11, 2015 at 2:25 PM Gor Nishanov <gornishanov@gmail.com> wrote:

> Yep. As soon as I add await_transform (probably later this week), you will
> be able to ban things like future<T> from coroutines returning expected<T>.
> It will look like this:
>
> namespace std { namespace experimental {
>
>    template <typename T> struct is_suspendable : true_type {}; //
> awaiting on anything can result in suspension
>
> }}
>
> Primary template states that by default we consider everything
> suspendable. We will specialize for expected to say that awaitng won't
> result in suspension:
>
> namespace std { namespace experimental {
>
>    template <typename T> struct is_suspendable<expected<T>> : false_type
> {}; // but not on expected
>
> }}
>
> And you add the following await_transform to the promise:
>
> template <typename Awaitable>
>
> enable_if<is_suspendable<Awaitable>::value> await_transform(Awaitable
> const&) {
>
>   static_assert(false, "expected<T> does not support awaiting on
> suspendable types");
>
> }
>
> Now you will get a nice compile time error if you, say, await on a future.
>
> On Wednesday, November 11, 2015 at 2:11:58 PM UTC-8, Shahms King wrote:
>
>> Without await_transform() how does this deal with awaiting on a
>> suspending awaitable from within a non-suspending promise?  At least with
>> the most recent wording I've seen, the above is unsafe as it allows:
>>
>> expected<T, E> unsafe() {
>>   auto value = await another_expected();  // Fine.
>>   auto next = await returns_a_future();  // Uh-oh, we've returned to our
>> caller without a value.
>>   return T{};
>> }
>>
>> --Shahms
>>
>>
>>
>> On Wed, Nov 11, 2015 at 2:05 PM Gor Nishanov <gorni...@gmail.com> wrote:
>>
> Please see attached file.
>>> Here are a usage example:
>>>
>>> expected<int> ok() { return 42; }
>>>
>>>
>>> expected<int> bad() { return{ error, 5 }; }
>>>
>>>
>>> expected<int> f() {
>>>
>>>   auto x = await ok();
>>>
>>>   auto y = await ok();
>>>
>>>   return x + y;
>>>
>>> }
>>>
>>>
>>> expected<int> g() {
>>>
>>>   auto x = await ok(); // unpacks result of OK into x
>>>
>>>   auto y = await bad(); // will propagate the error as the result of g()
>>>
>>>   return x + y;
>>>
>>> }
>>>
>>> Coroutine promise for the function returning expected<T> is:
>>>
>>> namespace std { namespace experimental {
>>>
>>>   template <typename T, typename... Whatever>
>>>
>>>   struct coroutine_traits<expected<T>, Whatever...> {
>>>
>>>     struct promise_type {
>>>
>>>       expected<T>* r;
>>>       void return_value(T val) { r->val = val; r->err = 0; }
>>>
>>>       void return_value(error_t, int err) { r->err = err; }
>>>
>>>       expected<T> get_return_object(expected<T>* x) { r = x; return
>>> expected<T>{}; }
>>>
>>>    };
>>>
>>>   };
>>>
>>> } }
>>>
>>>
>>> Note, this works with private version of compiler with a few tweaks that
>>> are not part of P0057R0/R1.
>>>
>>> Namely, I made initial_suspend/final_suspend optional. If
>>> coroutine_promise does not have those, coroutine is not meant to be
>>> suspended.
>>> Second tweak, (not sure if I like it, I am still experimenting), if
>>> coroutine is not suspendable, I pass a pointer to a value being returned to
>>> a get_return_object, this allows to deal with values like expected that are
>>> not split into consuming part (future) and the promise. I can also
>>> implement it without changing the get_return_object at all, but, that will
>>> require clarification in wording that in non-suspending coroutines
>>> get_return_object is called after user authored body is completed, as
>>> opposed to before user authored body is entered as it is traditional
>>> coroutines.
>>>
>>> --
>>>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>
>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>
>>
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e013c5db643863d05244b7e80
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">That certainly was my hope when I saw the mention of await=
_transform() in the &quot;future directions&quot;.=C2=A0 Although the extra=
 type_traits machinery is awkward, I don&#39;t see any way of avoiding it w=
ithout pushing the mechanism onto the awaitable via the type of the corouti=
ne_handle.<div><br></div><div>--Shahms<br><br><div class=3D"gmail_quote"><d=
iv dir=3D"ltr">On Wed, Nov 11, 2015 at 2:25 PM Gor Nishanov &lt;<a href=3D"=
mailto:gornishanov@gmail.com">gornishanov@gmail.com</a>&gt; wrote:<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Yep. As soon as I add=
 await_transform (probably later this week), you will be able to ban things=
 like future&lt;T&gt; from coroutines returning expected&lt;T&gt;.</div><di=
v>It will look like this:</div><div><br></div><div><p><font color=3D"#0000f=
f" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2"> std { </font></font><font color=3D"#0000ff" face=3D"Consolas"=
 size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font colo=
r=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></font></font><f=
ont face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> experi=
mental {</font></font></p><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0 template</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
 &lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">typename</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"C=
onsolas" size=3D"2">&gt; </font></font><font color=3D"#0000ff" face=3D"Cons=
olas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2">struct</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2"> : </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">true_type</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2"> {}; </font></font><font color=3D"#008000" face=
=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"=
2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">// awaiting on anyt=
hing can result in suspension</font></font></font></p><font color=3D"#00800=
0" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">
</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Conso=
las" size=3D"2"><p>}}</p></font></font></div><div><br></div><div>Primary te=
mplate states that by default we consider everything suspendable. We will s=
pecialize for expected to say that=C2=A0awaitng=C2=A0won&#39;t result in su=
spension:</div><div><br></div><div><p><font color=3D"#0000ff" face=3D"Conso=
las" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font =
color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></font></fon=
t><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> st=
d { </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2">namespace</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> experimental {</font><=
/font></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0 template</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
 &lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">typename</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"C=
onsolas" size=3D"2">&gt; </font></font><font color=3D"#0000ff" face=3D"Cons=
olas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2">struct</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font c=
olor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font fa=
ce=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;&gt; : </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"=
><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91a=
f" face=3D"Consolas" size=3D"2">false_type</font></font></font><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {}; </font></f=
ont><font color=3D"#008000" face=3D"Consolas" size=3D"2"><font color=3D"#00=
8000" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Consolas=
" size=3D"2">// but not on expected</font></font></font></p><font color=3D"=
#008000" face=3D"Consolas" size=3D"2"><font color=3D"#008000" face=3D"Conso=
las" size=3D"2"><font color=3D"#008000" face=3D"Consolas" size=3D"2">
</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Conso=
las" size=3D"2"><p>}}</p></font></font></div><div><br></div><div><div>And y=
ou add the following await_transform to the promise:</div><div><br></div></=
div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">   </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fo=
nt color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" f=
ace=3D"Consolas" size=3D"2">template</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;</font></font><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2">typename</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">Awaitable</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&gt;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2">enable_if</font></font></font><fo=
nt face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</fo=
nt></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">is_suspendable</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font c=
olor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2">Awaitable</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&gt;::value&gt; await_transform(</font></font><=
font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af"=
 face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2">Awaitable</font></font></font><font face=3D"Consolas" size=3D"2"><f=
ont face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">const</font></font=
></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"=
2">&amp;) {</font></font></p><div><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 static_assert</font></font=
></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"=
2">(</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2">false</font></font></font><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></font><font color=
=3D"#a31515" face=3D"Consolas" size=3D"2"><font color=3D"#a31515" face=3D"C=
onsolas" size=3D"2"><font color=3D"#a31515" face=3D"Consolas" size=3D"2">&q=
uot;expected&lt;T&gt; does not support awaiting on suspendable types&quot;<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">);</font></font></p><div><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>   }</p></font></font><div><br></div><div>Now you will ge=
t a nice compile time error if you, say, await on a future.</div></div><div=
 dir=3D"ltr"><div><br>On Wednesday, November 11, 2015 at 2:11:58 PM UTC-8, =
Shahms King wrote:</div></div><div dir=3D"ltr"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr">Without await_transform() how does this deal w=
ith awaiting on a suspending awaitable from within a non-suspending promise=
?=C2=A0 At least with the most recent wording I&#39;ve seen, the above is u=
nsafe as it allows:<div><br></div><div>expected&lt;T, E&gt; unsafe() {</div=
><div>=C2=A0 auto value =3D await another_expected(); =C2=A0// Fine.</div><=
div>=C2=A0 auto next =3D await returns_a_future(); =C2=A0// Uh-oh, we&#39;v=
e returned to our caller without a value.</div><div>=C2=A0 return T{};</div=
><div>}</div><div><br></div><div>--Shahms<br><div><br></div><div><br></div>=
</div></div><br></blockquote></div><div dir=3D"ltr"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Nov 11=
, 2015 at 2:05 PM Gor Nishanov &lt;<a rel=3D"nofollow">gorni...@gmail.com</=
a>&gt; wrote:<br></div></div></blockquote></div><div dir=3D"ltr"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div>Please see attached file. </div><div>He=
re are a usage example:</div><div><br></div><p><font face=3D"Consolas" size=
=3D"2"><font face=3D"Consolas" size=3D"2">expected&lt;</font></font><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2">int</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D=
"Consolas" size=3D"2">&gt; ok() { </font></font><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font></fon=
t></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D=
"2"> 42; }</font></font></p><p><font face=3D"Consolas" size=3D"2"><br></fon=
t></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">
</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; bad() { <=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">return</font></font></font><font face=3D"Consolas" si=
ze=3D"2"><font face=3D"Consolas" size=3D"2">{ error, 5 }; }</font></font></=
p><p><font face=3D"Consolas" size=3D"2"><br></font></p><div><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; f() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok();</font></font></p><div>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><p><br></p></font></font><div><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">

</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"></font></font></font></div><p><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" =
size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">expected</f=
ont></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas=
" size=3D"2">&lt;</font></font><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">int</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; g() {</fo=
nt></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"Consola=
s" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> ok(); // unpacks result of O=
K into x</font></font></p><div><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 auto</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> y =3D=
 </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">await</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> bad(); // will propagate the=
 error as the result of g()</font></font></p><div><font face=3D"Consolas" s=
ize=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font></div><p><font face=3D"Consolas" size=3D"2"><font face=3D"Con=
solas" size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 return</font></font></font=
><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> x +=
 y;</font></font></p><div><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">
</font></font></div><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2"><p>}</p><div><br></div><div>Coroutine promise for the functi=
on returning expected&lt;T&gt; is:</div><div><br></div><div><p><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">na=
mespace</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2"> std { </font></font><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"=
2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">namespace</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2"> experimental {</font></font></p><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">=C2=A0 template</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> &lt;<=
/font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D=
"Consolas" size=3D"2">typename</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Cons=
olas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</fo=
nt></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2">, </font></font><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"=
#0000ff" face=3D"Consolas" size=3D"2">typename</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">... </font></=
font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2=
b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consola=
s" size=3D"2">Whatever</font></font></font><font face=3D"Consolas" size=3D"=
2"><font face=3D"Consolas" size=3D"2">&gt;</font></font></p><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0struct</font></font></font><=
font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </fon=
t></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2">coroutine_traits</font></font></font><font face=3D"Cons=
olas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D=
"2">expected</font></font></font><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;, </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2">Whatever</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">...&gt; {</font></font><=
/p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"></font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D=
"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#00=
00ff" face=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0 struct</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font =
color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2">promise_type</font></font></font><font face=3D"Con=
solas" size=3D"2"><font face=3D"Consolas" size=3D"2"> {</font></font></p><f=
ont face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt;* r;</font></font></=
p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font co=
lor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font><=
/font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"=
> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font=
 color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D=
"2">val</font></font></font><font face=3D"Consolas" size=3D"2"><font face=
=3D"Consolas" size=3D"2">) { r-&gt;val =3D </font></font><font color=3D"#80=
8080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">val</font=
></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" s=
ize=3D"2">; r-&gt;err =3D 0; }</font></font><font face=3D"Consolas" size=3D=
"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font=
 color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void</font></font>=
</font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
"> return_value(</font></font><font color=3D"#2b91af" face=3D"Consolas" siz=
e=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D=
"#2b91af" face=3D"Consolas" size=3D"2">error_t</font></font></font><font fa=
ce=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></fo=
nt><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#000=
0ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas"=
 size=3D"2">int</font></font></font><font face=3D"Consolas" size=3D"2"><fon=
t face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#808080" face=
=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"=
2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></=
font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">=
) { r-&gt;err =3D </font></font><font color=3D"#808080" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2">err</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">; }</font></fo=
nt></p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">
</font></font><p><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font=
 color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fac=
e=3D"Consolas" size=3D"2">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 expected</font></f=
ont></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">&lt;</font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">&gt; get_return_object(<=
/font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font col=
or=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D=
"Consolas" size=3D"2">expected</font></font></font><font face=3D"Consolas" =
size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font><font color=
=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"C=
onsolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T<=
/font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consol=
as" size=3D"2">&gt;* </font></font><font color=3D"#808080" face=3D"Consolas=
" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font col=
or=3D"#808080" face=3D"Consolas" size=3D"2">x</font></font></font><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">) { r =3D </fo=
nt></font><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=
=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"C=
onsolas" size=3D"2">x</font></font></font><font face=3D"Consolas" size=3D"2=
"><font face=3D"Consolas" size=3D"2">; </font></font><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">return</font>=
</font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" si=
ze=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2=
"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2">expected</font></font></font><font face=3D=
"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></font>=
<font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af=
" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" si=
ze=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font fac=
e=3D"Consolas" size=3D"2">&gt;{}; }</font></font></p><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2">
<p>=C2=A0=C2=A0 };</p>
<p>=C2=A0=C2=A0};</p>
<p>} }</p><p><br></p><p>Note, this works with private version of compiler w=
ith a few tweaks that are not part of P0057R0/R1.</p><div><br></div><div>Na=
mely, I made initial_suspend/final_suspend optional. If coroutine_promise d=
oes not have those, coroutine is not meant to be suspended.</div><div>Secon=
d tweak, (not sure if I like it, I am still experimenting), if coroutine is=
 not suspendable, I pass a pointer to a value being returned to a get_retur=
n_object, this allows to deal with values like expected that are not split =
into consuming part (future) and the promise. I can also implement it witho=
ut changing the get_return_object at all, but, that will require clarificat=
ion in wording that in non-suspending coroutines get_return_object is calle=
d after user authored body is completed, as opposed to before user authored=
 body is entered as it is traditional coroutines.</div></font></font></div>=
</font></font></div>

<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></blockquote></div=
></blockquote></div><div dir=3D"ltr"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.</blockquote></div></blockquote></div><div dir=3D"ltr"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div class=3D"gmail_quote"><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"nofollow" target=3D"_blank">http://groups.google.com=
/a/isocpp.org/group/std-proposals/</a>.<br>
</blockquote></div></blockquote></div>

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</blockquote></div></div></div>

<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 />

--089e013c5db643863d05244b7e80--

.


Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 11 Nov 2015 14:48:10 -0800 (PST)
Raw View
------=_Part_49_558184508.1447282090236
Content-Type: multipart/alternative;
 boundary="----=_Part_50_1342788807.1447282090236"

------=_Part_50_1342788807.1447282090236
Content-Type: text/plain; charset=UTF-8

My bad. See the attached file now. (await_transform is not hooked up yet,
it is there as an illustration).

On Wednesday, November 11, 2015 at 2:27:11 PM UTC-8, Nicol Bolas wrote:
>
> On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishanov wrote:
>>
>> Please see attached file
>>
>
> I don't see an attachment in your post. But I do see the code you put into
> the post.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_50_1342788807.1447282090236
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">My bad. See the attached file now. (await_transform is not=
 hooked up yet, it is there as an illustration).<br><br>On Wednesday, Novem=
ber 11, 2015 at 2:27:11 PM UTC-8, Nicol Bolas wrote:<blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr">On Wednesday, November 11, 2015 at 5=
:05:02 PM UTC-5, Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>Please see attached file</div></div></blockquote><di=
v><br>I don&#39;t see an attachment in your post. But I do see the code you=
 put into the post.</div></div></blockquote></div>

<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 />

------=_Part_50_1342788807.1447282090236--
------=_Part_49_558184508.1447282090236
Content-Type: text/x-c++src; charset=US-ASCII; name=expected.cpp
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=expected.cpp
X-Attachment-Id: e0edbebc-2925-4260-8402-40c616ec8d97
Content-ID: <e0edbebc-2925-4260-8402-40c616ec8d97>

#include <stdio.h>
#include <cassert>
#include <experimental/resumable>
#include <type_traits>

namespace std { namespace experimental {
  template <typename T> struct is_suspendable : true_type {}; // awaiting on anything can result in suspension
}}

// quick mockup of expected
struct error_t {};
constexpr error_t error;

template <typename T>
struct expected {
 int err;
 T val;

 expected() {}
 expected(T value) : err(0),val(value) {}
 expected(error_t, int err) : err(err) {}

 bool has_value() { return err == 0; }
 bool has_error() { return !has_value(); }
 explicit operator bool() { return has_value(); }

 T const& value() const { assert(has_value()); return val; }
 T & value() { assert(has_value()); return val; }

 int error() { assert(has_error()); return err; }

 void print() {
  if (has_value()) printf("%d\n", val);
  else printf("err:%d\n", err);
 }
};

namespace std { namespace experimental {
  template <typename T> struct is_suspendable<expected<T>> : false_type {}; // but not on expected
}}

namespace std { namespace experimental {
 template <typename T, typename... Whatever>
 struct coroutine_traits<expected<T>, Whatever...> {
  struct promise_type {
   expected<T>* r;
   void return_value(T val) { r->val = val; r->err = 0; }
   void return_value(error_t, int err) { r->err = err; }
   expected<T> get_return_object(expected<T>* x) { r = x; return expected<T>{}; }

   template <typename Awaitable>
   enable_if<is_suspendable<Awaitable>::value> await_transform(Awaitable const&) {
    static_assert(false, "expected<T> does not support awaiting on suspendable types");
   }
  };
 };
} }

template <typename T>
bool await_ready(expected<T> & val) {
 return val.has_value();
}

template <typename T>
T await_resume(expected<T> & val) {
 return val.value();
}

template <typename T, typename P>
void await_suspend(expected<T> & val, std::experimental::coroutine_handle<P> h) {
 h.promise().return_value(error, val.error());
 h.destroy();
}

expected<int> ok() { return 42; }
expected<int> bad() { return{ error, 5 }; }

expected<int> f() {
 auto x = await ok();
 auto y = await ok();
 return x + y;
}

expected<int> g() {
 auto x = await ok();
 auto y = await bad();
 return x + y;
}

int main() {
 ok().print();
 bad().print();
 f().print();
 g().print();
}
------=_Part_49_558184508.1447282090236--

.


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

Le 11/11/2015 23:27, Nicol Bolas a =C3=A9crit :
> On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishanov wrote:
>> Please see attached file
>>
> I don't see an attachment in your post. But I do see the code you put int=
o
> the post.
>
> One thing it's missing is the awaiter type. Or if `expected` has the
> appropriate interface, I don't see how that gets implemented. I want to s=
ee
> what `await_ready`, `await_suspend` and `await_resume` do for an `expecte=
d`.
>
> Here are a usage example:
>> expected<int> ok() { return 42; }
>>
>>
>> expected<int> bad() { return{ error, 5 }; }
>>
>>
>> expected<int> f() {
>>
>>    auto x =3D await ok();
>>
>>    auto y =3D await ok();
>>
>>    return x + y;
>>
>> }
>>
>>
>> expected<int> g() {
>>
>>    auto x =3D await ok(); // unpacks result of OK into x
>>
>>    auto y =3D await bad(); // will propagate the error as the result of =
g()
>>
>>    return x + y;
>>
>> }
>>
>> Coroutine promise for the function returning expected<T> is:
>>
>> namespace std { namespace experimental {
>>
>>    template <typename T, typename... Whatever>
>>
>>    struct coroutine_traits<expected<T>, Whatever...> {
>>
>>      struct promise_type {
>>
>>        expected<T>* r;
>>        void return_value(T val) { r->val =3D val; r->err =3D 0; }
>>
>>        void return_value(error_t, int err) { r->err =3D err; }
>>
>>        expected<T> get_return_object(expected<T>* x) { r =3D x; return
>> expected<T>{}; }
>>
>>     };
>>
>>    };
>>
>> } }
>>
>>
>> Note, this works with private version of compiler with a few tweaks that
>> are not part of P0057R0/R1.
>>
> I'd call something like this a bit more than a "tweak". You're effectivel=
y
> defining a new kind of coroutine.
>
As goto and addressing the memory directly?

I believe the name of the baby could change in the future.

For me await is the Haskel do-notation but for C++ (which is much more=20
complex).

The initial goal of await was to simplify complex .then() chaining for=20
futures. But futures are monads and .then is something similar mbind.
While the generalization was done it was done based on the interface=20
futures provide. Now we see that we can do it for any monadic type.

await is sure something more than do-notation, bit IMO it is not only=20
useful for coroutines.

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/.

--------------080004010003080508070200
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/2015 23:27, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:05716343-e47a-4712-b93e-c3b4e7dfc901@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, G=
or Nishanov wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">
Please see attached file

</pre>
      </blockquote>
      <pre wrap=3D"">
I don't see an attachment in your post. But I do see the code you put into=
=20
the post.

One thing it's missing is the awaiter type. Or if `expected` has the=20
appropriate interface, I don't see how that gets implemented. I want to see=
=20
what `await_ready`, `await_suspend` and `await_resume` do for an `expected`=
..

Here are a usage example:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">
expected&lt;int&gt; ok() { return 42; }


expected&lt;int&gt; bad() { return{ error, 5 }; }


expected&lt;int&gt; f() {

  auto x =3D await ok();

  auto y =3D await ok();

  return x + y;

}


expected&lt;int&gt; g() {

  auto x =3D await ok(); // unpacks result of OK into x

  auto y =3D await bad(); // will propagate the error as the result of g()

  return x + y;

}

Coroutine promise for the function returning expected&lt;T&gt; is:

namespace std { namespace experimental {

  template &lt;typename T, typename... Whatever&gt;

  struct coroutine_traits&lt;expected&lt;T&gt;, Whatever...&gt; {

    struct promise_type {

      expected&lt;T&gt;* r;
      void return_value(T val) { r-&gt;val =3D val; r-&gt;err =3D 0; }=20

      void return_value(error_t, int err) { r-&gt;err =3D err; }

      expected&lt;T&gt; get_return_object(expected&lt;T&gt;* x) { r =3D x; =
return=20
expected&lt;T&gt;{}; }

   };

  };

} }


Note, this works with private version of compiler with a few tweaks that=20
are not part of P0057R0/R1.

</pre>
      </blockquote>
      <pre wrap=3D"">
I'd call something like this a bit more than a "tweak". You're effectively=
=20
defining a new kind of coroutine.

</pre>
    </blockquote>
    <font size=3D"+1">As goto and addressing the memory directly?<br>
      <br>
      I believe the name of the baby could change in the future.<br>
      <br>
      For me await is the Haskel do-notation but for C++ (which is much
      more complex).<br>
      <br>
      The initial goal of await was to simplify complex .then() chaining
      for futures. But futures are monads and .then is something similar
      mbind. <br>
      While the generalization was done it was done based on the
      interface futures provide. Now we see that we can do it for any
      monadic type.<br>
      <br>
      await is sure something more than do-notation, bit IMO it is not
      only useful for coroutines.<br>
      <br>
      Vicente=C2=A0 <br>
    </font>
  </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 />

--------------080004010003080508070200--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Nov 2015 15:14:31 -0800 (PST)
Raw View
------=_Part_1083_597765725.1447283671880
Content-Type: multipart/alternative;
 boundary="----=_Part_1084_201359144.1447283671881"

------=_Part_1084_201359144.1447283671881
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, November 11, 2015 at 5:57:00 PM UTC-5, Vicente J. Botet=20
Escriba wrote:
>
> Le 11/11/2015 23:27, Nicol Bolas a =C3=A9crit :
>
> On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishanov wrote:
>
> Please see attached file
>
>
> I don't see an attachment in your post. But I do see the code you put int=
o=20
> the post.
>
> One thing it's missing is the awaiter type. Or if `expected` has the=20
> appropriate interface, I don't see how that gets implemented. I want to s=
ee=20
> what `await_ready`, `await_suspend` and `await_resume` do for an `expecte=
d`.
>
> Here are a usage example:
>
> expected<int> ok() { return 42; }
>
>
> expected<int> bad() { return{ error, 5 }; }
>
>
> expected<int> f() {
>
>   auto x =3D await ok();
>
>   auto y =3D await ok();
>
>   return x + y;
>
> }
>
>
> expected<int> g() {
>
>   auto x =3D await ok(); // unpacks result of OK into x
>
>   auto y =3D await bad(); // will propagate the error as the result of g(=
)
>
>   return x + y;
>
> }
>
> Coroutine promise for the function returning expected<T> is:
>
> namespace std { namespace experimental {
>
>   template <typename T, typename... Whatever>
>
>   struct coroutine_traits<expected<T>, Whatever...> {
>
>     struct promise_type {
>
>       expected<T>* r;
>       void return_value(T val) { r->val =3D val; r->err =3D 0; }=20
>
>       void return_value(error_t, int err) { r->err =3D err; }
>
>       expected<T> get_return_object(expected<T>* x) { r =3D x; return=20
> expected<T>{}; }
>
>    };
>
>   };
>
> } }
>
>
> Note, this works with private version of compiler with a few tweaks that=
=20
> are not part of P0057R0/R1.
>
>
> I'd call something like this a bit more than a "tweak". You're effectivel=
y=20
> defining a new kind of coroutine.
>
>
> As goto and addressing the memory directly?
>
> I believe the name of the baby could change in the future.
>
> For me await is the Haskel do-notation but for C++ (which is much more=20
> complex).
>
> The initial goal of await was to simplify complex .then() chaining for=20
> futures. But futures are monads and .then is something similar mbind.=20
> While the generalization was done it was done based on the interface=20
> futures provide. Now we see that we can do it for any monadic type.
>
> await is sure something more than do-notation, bit IMO it is not only=20
> useful for coroutines.
>

Then it shouldn't be spelled "await". If it's not at least potentially=20
waiting on something, then it should be called something else. When you're=
=20
starting to change the design of a generally complete feature just to cover=
=20
someone's pet use case, that becomes problematic.

--=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/.

------=_Part_1084_201359144.1447283671881
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, November 11, 2015 at 5:57:00 PM UTC-5, Vicente J. Botet Escri=
ba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 11/11/2015 23:27, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <pre>On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishano=
v wrote:
</pre>
      <blockquote type=3D"cite">
        <pre>Please see attached file

</pre>
      </blockquote>
      <pre>I don&#39;t see an attachment in your post. But I do see the cod=
e you put into=20
the post.

One thing it&#39;s missing is the awaiter type. Or if `expected` has the=20
appropriate interface, I don&#39;t see how that gets implemented. I want to=
 see=20
what `await_ready`, `await_suspend` and `await_resume` do for an `expected`=
..

Here are a usage example:
</pre>
      <blockquote type=3D"cite">
        <pre>expected&lt;int&gt; ok() { return 42; }


expected&lt;int&gt; bad() { return{ error, 5 }; }


expected&lt;int&gt; f() {

  auto x =3D await ok();

  auto y =3D await ok();

  return x + y;

}


expected&lt;int&gt; g() {

  auto x =3D await ok(); // unpacks result of OK into x

  auto y =3D await bad(); // will propagate the error as the result of g()

  return x + y;

}

Coroutine promise for the function returning expected&lt;T&gt; is:

namespace std { namespace experimental {

  template &lt;typename T, typename... Whatever&gt;

  struct coroutine_traits&lt;expected&lt;T&gt;, Whatever...&gt; {

    struct promise_type {

      expected&lt;T&gt;* r;
      void return_value(T val) { r-&gt;val =3D val; r-&gt;err =3D 0; }=20

      void return_value(error_t, int err) { r-&gt;err =3D err; }

      expected&lt;T&gt; get_return_object(expected&lt;T&gt;* x) { r =3D x; =
return=20
expected&lt;T&gt;{}; }

   };

  };

} }


Note, this works with private version of compiler with a few tweaks that=20
are not part of P0057R0/R1.

</pre>
      </blockquote>
      <pre>I&#39;d call something like this a bit more than a &quot;tweak&q=
uot;. You&#39;re effectively=20
defining a new kind of coroutine.

</pre>
    </blockquote>
    <font size=3D"+1">As goto and addressing the memory directly?<br>
      <br>
      I believe the name of the baby could change in the future.<br>
      <br>
      For me await is the Haskel do-notation but for C++ (which is much
      more complex).<br>
      <br>
      The initial goal of await was to simplify complex .then() chaining
      for futures. But futures are monads and .then is something similar
      mbind. <br>
      While the generalization was done it was done based on the
      interface futures provide. Now we see that we can do it for any
      monadic type.<br>
      <br>
      await is sure something more than do-notation, bit IMO it is not
      only useful for coroutines.</font></div></blockquote><br>Then it shou=
ldn&#39;t be spelled &quot;await&quot;. If it&#39;s not at least potentiall=
y waiting on something, then it should be called something else. When you&#=
39;re starting to change the design of a generally complete feature just to=
 cover someone&#39;s pet use case, that becomes problematic.<br>

<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 />

------=_Part_1084_201359144.1447283671881--
------=_Part_1083_597765725.1447283671880--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Nov 2015 15:51:09 -0800 (PST)
Raw View
------=_Part_8146_1628386530.1447285870111
Content-Type: multipart/alternative;
 boundary="----=_Part_8147_1781006040.1447285870111"

------=_Part_8147_1781006040.1447285870111
Content-Type: text/plain; charset=UTF-8

On Wednesday, November 11, 2015 at 5:48:10 PM UTC-5, Gor Nishanov wrote:
>
> My bad. See the attached file now. (await_transform is not hooked up yet,
> it is there as an illustration).
>
> On Wednesday, November 11, 2015 at 2:27:11 PM UTC-8, Nicol Bolas wrote:
>>
>> On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor Nishanov wrote:
>>>
>>> Please see attached file
>>>
>>
>> I don't see an attachment in your post. But I do see the code you put
>> into the post.
>>
>
OK, let's take a look at await_suspend:

template <typename T, typename P>
void await_suspend(expected<T> & val, std::experimental::coroutine_handle<P>
h) {
    h.promise().return_value(error, val.error());
    h.destroy();
}

That's... terrifying.

So the function destroys the coroutine_handle. Notably, the handle for the
function that it's currently executing within. After all, until the
suspend-resume-point is reached, we're still in the body of that function
(though to be fair, we'll hit that immediately after executing that
statement). Isn't that a bit dangerous?

Also, as I understand it, the coroutine_handle holds the function's stack.
Isn't the promise object on the stack? So wouldn't destroying it
automatically destroy every object on the stack, including the promise? So
how does the caller get a return value?

Obviously, I don't have access to your specific implementation of resumable
functions, so things may have changed. But it seems to me like somebody's
talking to a dead object.

If you're going to have non-resumable coroutines (which sounds like an
oxymoron, given your definition of "coroutine"), if you want to allow
people to basically hijack promises and `await` to terminate the function
without an explicit return, maybe there should be some kind of *explicit*
support for that. A coroutine_trait like you mentioned. That way, the
await_suspend function doesn't have to do that kind of dangerous handle
destruction.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_8147_1781006040.1447285870111
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, November 11, 2015 at 5:48:10 PM UTC-5, Gor N=
ishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>My bad. See the attached file now. (await_transform is not hooked up yet, =
it is there as an illustration).<br><br>On Wednesday, November 11, 2015 at =
2:27:11 PM UTC-8, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr">On Wednesday, November 11, 2015 at 5:05:02 PM UTC-5, Gor =
Nishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>Please see attached file</div></div></blockquote><div><br>I don&#39;t see=
 an attachment in your post. But I do see the code you put into the post.</=
div></div></blockquote></div></blockquote><div><br>OK, let&#39;s take a loo=
k at await_suspend:<br><br><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"style=
d-by-prettify">template</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ty=
pename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> P</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> await_suspend</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">expected</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> val</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">experimental</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">coroutine_handle</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">P</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> h</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 h</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">promise</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">().</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">return_value</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">error</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> val</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
error</span><span style=3D"color: #660;" class=3D"styled-by-prettify">());<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 h</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">destroy</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div>=
<br>That&#39;s... terrifying.<br><br>So the function destroys the coroutine=
_handle. Notably, the handle for the function that it&#39;s currently execu=
ting within. After all, until the suspend-resume-point is reached, we&#39;r=
e still in the body of that function (though to be fair, we&#39;ll hit that=
 immediately after executing that statement). Isn&#39;t that a bit dangerou=
s?<br><br>Also, as I understand it, the coroutine_handle holds the function=
&#39;s stack. Isn&#39;t the promise object on the stack? So wouldn&#39;t de=
stroying it automatically destroy every object on the stack, including the =
promise? So how does the caller get a return value?<br><br>Obviously, I don=
&#39;t have access to your specific implementation of resumable functions, =
so things may have changed. But it seems to me like somebody&#39;s talking =
to a dead object.<br><br>If you&#39;re going to have non-resumable coroutin=
es (which sounds like an oxymoron, given your definition of &quot;coroutine=
&quot;), if you want to allow people to basically hijack promises and `awai=
t` to terminate the function without an explicit return, maybe there should=
 be some kind of <i>explicit</i> support for that. A coroutine_trait like y=
ou mentioned. That way, the await_suspend function doesn&#39;t have to do t=
hat kind of dangerous handle destruction.<br></div></div>

<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 />

------=_Part_8147_1781006040.1447285870111--
------=_Part_8146_1628386530.1447285870111--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 12 Nov 2015 06:10:18 -0800 (PST)
Raw View
------=_Part_9546_1468827651.1447337418588
Content-Type: multipart/alternative;
 boundary="----=_Part_9547_1329240104.1447337418588"

------=_Part_9547_1329240104.1447337418588
Content-Type: text/plain; charset=UTF-8

OK, let's see if I can reply to Gor's mail directly to the forum.

On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:

> For some reason, google group keeps deleting my messages :-) . Let's see
> if replying via e-mail help.
>
> So the function destroys the coroutine_handle. Notably, the handle for the
>> function that it's currently executing within. After all, until the
>> suspend-resume-point is reached, we're still in the body of that function
>> (though to be fair, we'll hit that immediately after executing that
>> statement). Isn't that a bit dangerous?
>>
>
> Coroutine is considered suspended before the call to await_suspend, thus
> calling any resumption member function such as resume() or destroy() are
> legal from await_suspend. P0057R0 was vague about that. It was clarified in
> P0057R1 which should be out this week in post-Kona mailing.
>

Fair enough.


>
>
>> Also, as I understand it, the coroutine_handle holds the function's
>> stack. Isn't the promise object on the stack? So wouldn't destroying it
>> automatically destroy every object on the stack, including the promise? So
>> how does the caller get a return value?
>>
>
> Due to RVO, return value is in the caller frame, it is not part of the
> coroutine frame.
>

But it's the promise that's responsible for setting its value.

coroutine_trait like you mentioned. That way, the await_suspend function
>> doesn't have to do that kind of dangerous handle destruction.
>>
>
> Possibly. This code is a day old. Maybe there are better ways of doing it.
> I will be also curious to see what clang guys come up with as this scenario
> is of interest to them as well.
>

There is also the issue that you have to add a bunch of extra machinery to
promise/future in order to be able to await on both an expected and a
future. That is, if your function looks like this:

future<expected<T, E>> foo()
{
  auto data = await long_process(); //Schedules execution for later.
  auto val = await data.something(); //Retrieves an `expected` and
propagates the error
  return val; //Should initialize the `T` part of the `expected`.
}

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_9547_1329240104.1447337418588
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_quote">OK, let&#39;s see if I can repl=
y to Gor&#39;s mail directly to the forum.<br><br>On Wed, Nov 11, 2015 at 7=
:46 PM, Gor Nishanov<span dir=3D"ltr"></span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><span style=3D"font-size:12.8px">For some re=
ason, google group keeps deleting my messages :-) . Let&#39;s see if replyi=
ng via e-mail help.</span><div style=3D"font-size:12.8px"><br></div><div cl=
ass=3D"gmail_extra" style=3D"font-size:12.8px"><div class=3D"gmail_quote"><=
span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:so=
lid;padding-left:1ex"><div dir=3D"ltr">So
 the function destroys the coroutine_handle. Notably, the handle for the
 function that it&#39;s currently executing within. After all, until the=20
suspend-resume-point is reached, we&#39;re still in the body of that=20
function (though to be fair, we&#39;ll hit that immediately after executing=
=20
that statement). Isn&#39;t that a bit dangerous?<br></div></blockquote><div=
><br></div></span><div><span style=3D"font-family:Arial;font-size:9.75pt">C=
oroutine
 is considered suspended before the call to await_suspend, thus calling=20
any resumption member function such as resume() or destroy() are legal=20
from await_suspend. P0057R0 was vague about that. It was clarified in=20
P0057R1 which should be out this week in post-Kona mailing.</span></div></d=
iv></div></div></blockquote><div><br>Fair enough.<br>=C2=A0<br></div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra" style=
=3D"font-size:12.8px"><div class=3D"gmail_quote"><span><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padd=
ing-left:1ex"><div dir=3D"ltr">Also,
 as I understand it, the coroutine_handle holds the function&#39;s stack.=
=20
Isn&#39;t the promise object on the stack? So wouldn&#39;t destroying it=20
automatically destroy every object on the stack, including the promise?=20
So how does the caller get a return value?<br></div></blockquote><div><br><=
/div></span><div>Due to RVO, return value is in the caller frame, it is not=
 part of the coroutine frame.<br></div></div></div></div></blockquote><div>=
<br>But it&#39;s the promise that&#39;s responsible for setting its value.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"=
gmail_extra" style=3D"font-size:12.8px"><div class=3D"gmail_quote"><div></d=
iv><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr">coroutine_trait
 like you mentioned. That way, the await_suspend function doesn&#39;t have=
=20
to do that kind of dangerous handle destruction.<br></div></blockquote><div=
><br></div></span><div>Possibly.
 This code is a day old. Maybe there are better ways of doing it. I will
 be also curious to see what clang guys come up with as this scenario is
 of interest to them as well.</div></div></div></div></blockquote><div><br>=
There is also the issue that you have to add a bunch of extra machinery to =
promise/future in order to be able to await on both an expected and a futur=
e. That is, if your function looks like this:<br><br><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">future</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">expected</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> E</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> data </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> await long_process</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">//Schedules execution for later.</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> val </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> await data</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">something</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
/Retrieves an `expected` and propagates the error</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> val</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//Should initialize the `T` part of the `expected`.</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div><=
br></div></div></div>

<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 />

------=_Part_9547_1329240104.1447337418588--
------=_Part_9546_1468827651.1447337418588--

.


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

Le 12/11/2015 15:10, Nicol Bolas a =C3=A9crit :
> OK, let's see if I can reply to Gor's mail directly to the forum.
>
> On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:
>
> There is also the issue that you have to add a bunch of extra machinery t=
o
> promise/future in order to be able to await on both an expected and a
> future. That is, if your function looks like this:
>
> future<expected<T, E>> foo()
> {
>    auto data =3D await long_process(); //Schedules execution for later.
>    auto val =3D await data.something(); //Retrieves an `expected` and
> propagates the error
>    return val; //Should initialize the `T` part of the `expected`.
> }
>
Who want to do that?

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/.

--------------010303080804080607040304
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 12/11/2015 15:10, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:aa5a8f33-b548-4eb3-b118-dee5929b4a48@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">OK, let's see if I can reply to Gor's mail directly to=
 the forum.

On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:

</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">
</pre>
      </blockquote>
      <pre wrap=3D"">
There is also the issue that you have to add a bunch of extra machinery to=
=20
promise/future in order to be able to await on both an expected and a=20
future. That is, if your function looks like this:

future&lt;expected&lt;T, E&gt;&gt; foo()
{
  auto data =3D await long_process(); //Schedules execution for later.
  auto val =3D await data.something(); //Retrieves an `expected` and=20
propagates the error
  return val; //Should initialize the `T` part of the `expected`.
}

</pre>
    </blockquote>
    <font size=3D"+1">Who want to do that?<br>
      <br>
      Vicente<br>
    </font>
  </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 />

--------------010303080804080607040304--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 12 Nov 2015 12:02:59 -0800 (PST)
Raw View
------=_Part_10910_1194259460.1447358579708
Content-Type: multipart/alternative;
 boundary="----=_Part_10911_673872671.1447358579709"

------=_Part_10911_673872671.1447358579709
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Thursday, November 12, 2015 at 2:08:59 PM UTC-5, Vicente J. Botet=20
Escriba wrote:
>
> Le 12/11/2015 15:10, Nicol Bolas a =C3=A9crit :
>
> OK, let's see if I can reply to Gor's mail directly to the forum.
>
> On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:
>
>
> There is also the issue that you have to add a bunch of extra machinery t=
o=20
> promise/future in order to be able to await on both an expected and a=20
> future. That is, if your function looks like this:
>
> future<expected<T, E>> foo()
> {
>   auto data =3D await long_process(); //Schedules execution for later.
>   auto val =3D await data.something(); //Retrieves an `expected` and=20
> propagates the error
>   return val; //Should initialize the `T` part of the `expected`.
> }
>
>
> Who want to do that?
>

Someone who's working in code where exceptions are forbidden, yet wants to=
=20
do asynchronous processing.=20

--=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/.

------=_Part_10911_673872671.1447358579709
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Thursday, November 12, 2015 at 2:08:59 PM UTC-5, Vicente J. Bote=
t Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 12/11/2015 15:10, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <pre>OK, let&#39;s see if I can reply to Gor&#39;s mail directly to t=
he forum.

On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:

</pre>
      <blockquote type=3D"cite">
        <pre></pre>
      </blockquote>
      <pre>There is also the issue that you have to add a bunch of extra ma=
chinery to=20
promise/future in order to be able to await on both an expected and a=20
future. That is, if your function looks like this:

future&lt;expected&lt;T, E&gt;&gt; foo()
{
  auto data =3D await long_process(); //Schedules execution for later.
  auto val =3D await data.something(); //Retrieves an `expected` and=20
propagates the error
  return val; //Should initialize the `T` part of the `expected`.
}

</pre>
    </blockquote>
    <font size=3D"+1">Who want to do that?<br></font></div></blockquote><di=
v><br>Someone who&#39;s working in code where exceptions are forbidden, yet=
 wants to do asynchronous processing. <br></div>

<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 />

------=_Part_10911_673872671.1447358579709--
------=_Part_10910_1194259460.1447358579708--

.


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

Le 12/11/2015 21:02, Nicol Bolas a =C3=A9crit :
>
> On Thursday, November 12, 2015 at 2:08:59 PM UTC-5, Vicente J. Botet
> Escriba wrote:
>> Le 12/11/2015 15:10, Nicol Bolas a =C3=A9crit :
>>
>> OK, let's see if I can reply to Gor's mail directly to the forum.
>>
>> On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:
>>
>>
>> There is also the issue that you have to add a bunch of extra machinery =
to
>> promise/future in order to be able to await on both an expected and a
>> future. That is, if your function looks like this:
>>
>> future<expected<T, E>> foo()
>> {
>>    auto data =3D await long_process(); //Schedules execution for later.
>>    auto val =3D await data.something(); //Retrieves an `expected` and
>> propagates the error
>>    return val; //Should initialize the `T` part of the `expected`.
>> }
>>
>>
>> Who want to do that?
>>
> Someone who's working in code where exceptions are forbidden, yet wants t=
o
> do asynchronous processing.
>
If I was one of them I will define my own class future<T, error_code>=20
and use expected<T, error_code> as storage.


BTW,

   auto val =3D await data.something();

Retrieves an `expected` and doesn't works, as if there is an error and=20
data.something() returns expected<T,E>, we would need as result future<T,E>=
..

Note that decltype(val) would be T, not expected<T,E>.


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/.

--------------050507000405090908010802
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 12/11/2015 21:02, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:47cbee22-0b20-497b-8ee2-8fd58ef32612@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">

On Thursday, November 12, 2015 at 2:08:59 PM UTC-5, Vicente J. Botet=20
Escriba wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">
Le 12/11/2015 15:10, Nicol Bolas a =C3=A9crit :

OK, let's see if I can reply to Gor's mail directly to the forum.

On Wed, Nov 11, 2015 at 7:46 PM, Gor Nishanov wrote:


There is also the issue that you have to add a bunch of extra machinery to=
=20
promise/future in order to be able to await on both an expected and a=20
future. That is, if your function looks like this:

future&lt;expected&lt;T, E&gt;&gt; foo()
{
  auto data =3D await long_process(); //Schedules execution for later.
  auto val =3D await data.something(); //Retrieves an `expected` and=20
propagates the error
  return val; //Should initialize the `T` part of the `expected`.
}


Who want to do that?

</pre>
      </blockquote>
      <pre wrap=3D"">
Someone who's working in code where exceptions are forbidden, yet wants to=
=20
do asynchronous processing.=20

</pre>
    </blockquote>
    <font size=3D"+1">If I was one of them I will define my own class
      future&lt;T, error_code&gt;</font> and use expected&lt;T,
    error_code&gt; as storage.<br>
    <br>
    <br>
    BTW, <br>
    <br>
    =C2=A0 auto val =3D await data.something();<br>
    <br>
    Retrieves an `expected` and doesn't works, as if there is an error
    and data.something() returns expected&lt;T,E&gt;, we would need as
    result future&lt;T,E&gt;.<br>
    <br>
    Note that decltype(val) would be T, not expected&lt;T,E&gt;.<br>
    <br>
    <br>
    Vicente<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 />

--------------050507000405090908010802--

.