Topic: N4015: Should expected be parametrized by a trait?


Author: Pierre Talbot <ptalbot@hyc.io>
Date: Tue, 24 Jun 2014 07:01:17 +0200
Raw View
Hi,

I'd like to discuss the section 7.2 of the proposal N4015 (adding a
class expected<T,E>). It adds a trait to expected, so the type becomes
expected<T,E,Traits>. It enables custom behavior in the value() method
in case an error is contained. For the moment, it launches a
bad_expected_access, but we might like to launch the contained exception
if E==std::exception_ptr or std::system_error if E==std::error_code. Or
maybe even assert(false).

Secondly, in the monadic methods (bind/then/map), the continuation can
throw an exception and we think it could be useful to customize the
behavior, for example we might want to catch and store the exception.
Follow a specialization of expected_traits for error_code:

template <class T>
struct expected_traits<expected<T, error_code>>
{
   static expected<T, error_code> catch_exception(exception_ptr e)
   {
     try{
       rethrow_exception(e);
     } catch(const system_error& e) {
       return make_unexpected(e.code());
     }
   }

   static void bad_access(error_code e)
   {
     throw system_error(e);
   }
};

Note that this trait would help people to interact with exception-style
code while keeping some guarantees about the exception safety. Also, a
default expected_traits is provided and mimics the current behavior
(throwing bad_expected_access and don't catch exception thrown by
continuation).

Do you think it worth adding a third template argument to expected for
this purpose?

Cheers,
Pierre Talbot

PS: It has been implemented without much troubles
(https://github.com/ptal/Boost.Expected/tree/expected_traits).

--

---
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: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 25 Jun 2014 00:55:46 -0700 (PDT)
Raw View
------=_Part_1776_19799683.1403682946640
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=BCytkownik Pierre Talbot=
=20
napisa=C5=82:
>
> Hi,=20
>
> I'd like to discuss the section 7.2 of the proposal N4015 (adding a=20
> class expected<T,E>). It adds a trait to expected, so the type becomes=20
> expected<T,E,Traits>. It enables custom behavior in the value() method=20
> in case an error is contained. For the moment, it launches a=20
> bad_expected_access, but we might like to launch the contained exception=
=20
> if E=3D=3Dstd::exception_ptr or std::system_error if E=3D=3Dstd::error_co=
de. Or=20
> maybe even assert(false).=20
>
> Secondly, in the monadic methods (bind/then/map), the continuation can=20
> throw an exception and we think it could be useful to customize the=20
> behavior, for example we might want to catch and store the exception.=20
> Follow a specialization of expected_traits for error_code:=20
>
> template <class T>=20
> struct expected_traits<expected<T, error_code>>=20
> {=20
>    static expected<T, error_code> catch_exception(exception_ptr e)=20
>    {=20
>      try{=20
>        rethrow_exception(e);=20
>      } catch(const system_error& e) {=20
>        return make_unexpected(e.code());=20
>      }=20
>    }=20
>
>    static void bad_access(error_code e)=20
>    {=20
>      throw system_error(e);=20
>    }=20
> };=20
>
> Note that this trait would help people to interact with exception-style=
=20
> code while keeping some guarantees about the exception safety. Also, a=20
> default expected_traits is provided and mimics the current behavior=20
> (throwing bad_expected_access and don't catch exception thrown by=20
> continuation).=20
>
> Do you think it worth adding a third template argument to expected for=20
> this purpose?=20
>

This dilemma brings me to section 7.8 of the proposal:=20
"As the behavior of expected<E,T> and expected<exception_ptr,T> differs in=
=20
a lot of points (at least currently), should expected<E,T> and=20
expected<exception_ptr,T> be represented by two different classes?"

Even w/o this dilemma you already propose to specialize 'expected<>' for=20
`exception_ptr` because it does something different. Additional traits only=
=20
make this feeling stronger that you will be trying to pack two different=20
things into the same name -- somewhat artificially. It looks that with=20
traits/policies you can stuff two absolutely unrelated types into one=20
template. Of course in your case they are not absolutely different, but=20
also the differences are not trivial. Andrei Alexandrescu, it seems, only=
=20
considered the exception_ptr case and it made sense because for this case=
=20
lots of problems becomes trivial to solve (e.g., you know what value()=20
should do).

And this particular problem aside, adding to many parameters is a problem=
=20
on its own. You are not standardizing one type anymore, but a series of=20
types potentially incompatible with one another. Will they be convertible=
=20
to one another? Who will decide which policy to use? The implementer of the=
=20
function or the caller. What if they have different preferences? Will I=20
need to translate one expected<> to another? There will be different types=
=20
floating around -- this is somewhat opposite to standardizing one. Consider=
=20
shared_ptr. Its deleter type is erased so that there is only one shared_ptr=
=20
type (for a given T).

Regards,
&rzej

--=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_1776_19799683.1403682946640
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=
=BCytkownik Pierre Talbot napisa=C5=82:<blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">Hi,
<br>
<br>I'd like to discuss the section 7.2 of the proposal N4015 (adding a=20
<br>class expected&lt;T,E&gt;). It adds a trait to expected, so the type be=
comes=20
<br>expected&lt;T,E,Traits&gt;. It enables custom behavior in the value() m=
ethod=20
<br>in case an error is contained. For the moment, it launches a=20
<br>bad_expected_access, but we might like to launch the contained exceptio=
n=20
<br>if E=3D=3Dstd::exception_ptr or std::system_error if E=3D=3Dstd::error_=
code. Or=20
<br>maybe even assert(false).
<br>
<br>Secondly, in the monadic methods (bind/then/map), the continuation can=
=20
<br>throw an exception and we think it could be useful to customize the=20
<br>behavior, for example we might want to catch and store the exception.=
=20
<br>Follow a specialization of expected_traits for error_code:
<br>
<br>template &lt;class T&gt;
<br>struct expected_traits&lt;expected&lt;T, error_code&gt;&gt;
<br>{
<br>&nbsp; &nbsp;static expected&lt;T, error_code&gt; catch_exception(excep=
tion_ptr e)
<br>&nbsp; &nbsp;{
<br>&nbsp; &nbsp; &nbsp;try{
<br>&nbsp; &nbsp; &nbsp; &nbsp;rethrow_exception(e);
<br>&nbsp; &nbsp; &nbsp;} catch(const system_error&amp; e) {
<br>&nbsp; &nbsp; &nbsp; &nbsp;return make_unexpected(e.code());
<br>&nbsp; &nbsp; &nbsp;}
<br>&nbsp; &nbsp;}
<br>
<br>&nbsp; &nbsp;static void bad_access(error_code e)
<br>&nbsp; &nbsp;{
<br>&nbsp; &nbsp; &nbsp;throw system_error(e);
<br>&nbsp; &nbsp;}
<br>};
<br>
<br>Note that this trait would help people to interact with exception-style=
=20
<br>code while keeping some guarantees about the exception safety. Also, a=
=20
<br>default expected_traits is provided and mimics the current behavior=20
<br>(throwing bad_expected_access and don't catch exception thrown by=20
<br>continuation).
<br>
<br>Do you think it worth adding a third template argument to expected for=
=20
<br>this purpose?
<br></blockquote><div><br>This dilemma brings me to section 7.8 of the prop=
osal: <br>"As the behavior of expected&lt;E,T&gt; and expected&lt;exception=
_ptr,T&gt; differs in a lot of points (at least currently), should expected=
&lt;E,T&gt; and expected&lt;exception_ptr,T&gt; be represented by two diffe=
rent classes?"<br><br>Even w/o this dilemma you already propose to speciali=
ze 'expected&lt;&gt;' for `exception_ptr` because it does something differe=
nt. Additional traits only make this feeling stronger that you will be tryi=
ng to pack two different things into the same name -- somewhat artificially=
.. It looks that with traits/policies you can stuff two absolutely unrelated=
 types into one template. Of course in your case they are not absolutely di=
fferent, but also the differences are not trivial. Andrei Alexandrescu, it =
seems, only considered the exception_ptr case and it made sense because for=
 this case lots of problems becomes trivial to solve (e.g., you know what v=
alue() should do).<br><br>And this particular problem aside, adding to many=
 parameters is a problem on its own. You are not standardizing one type any=
more, but a series of types potentially incompatible with one another. Will=
 they be convertible to one another? Who will decide which policy to use? T=
he implementer of the function or the caller. What if they have different p=
references? Will I need to translate one expected&lt;&gt; to another? There=
 will be different types floating around -- this is somewhat opposite to st=
andardizing one. Consider shared_ptr. Its deleter type is erased so that th=
ere is only one shared_ptr type (for a given T).<br><br>Regards,<br>&amp;rz=
ej<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_1776_19799683.1403682946640--

.


Author: Pierre Talbot <ptalbot@hyc.io>
Date: Wed, 25 Jun 2014 14:34:41 +0200
Raw View
This is a multi-part message in MIME format.
--------------010109000901050804000807
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable


Le 25/06/2014 09:55, Andrzej Krzemie=C5=84ski a =C3=A9crit :
>
>
> W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=BCytkownik Pierre Talb=
ot=20
> napisa=C5=82:
>
>     Hi,
>
>     I'd like to discuss the section 7.2 of the proposal N4015 (adding a
>     class expected<T,E>). It adds a trait to expected, so the type
>     becomes
>     expected<T,E,Traits>. It enables custom behavior in the value()
>     method
>     in case an error is contained. For the moment, it launches a
>     bad_expected_access, but we might like to launch the contained
>     exception
>     if E=3D=3Dstd::exception_ptr or std::system_error if
>     E=3D=3Dstd::error_code. Or
>     maybe even assert(false).
>
>     Secondly, in the monadic methods (bind/then/map), the continuation
>     can
>     throw an exception and we think it could be useful to customize the
>     behavior, for example we might want to catch and store the exception.
>     Follow a specialization of expected_traits for error_code:
>
>     template <class T>
>     struct expected_traits<expected<T, error_code>>
>     {
>        static expected<T, error_code> catch_exception(exception_ptr e)
>        {
>          try{
>            rethrow_exception(e);
>          } catch(const system_error& e) {
>            return make_unexpected(e.code());
>          }
>        }
>
>        static void bad_access(error_code e)
>        {
>          throw system_error(e);
>        }
>     };
>
>     Note that this trait would help people to interact with
>     exception-style
>     code while keeping some guarantees about the exception safety.
>     Also, a
>     default expected_traits is provided and mimics the current behavior
>     (throwing bad_expected_access and don't catch exception thrown by
>     continuation).
>
>     Do you think it worth adding a third template argument to expected
>     for
>     this purpose?
>
>
> This dilemma brings me to section 7.8 of the proposal:
> "As the behavior of expected<E,T> and expected<exception_ptr,T>=20
> differs in a lot of points (at least currently), should expected<E,T>=20
> and expected<exception_ptr,T> be represented by two different classes?"
>
> Even w/o this dilemma you already propose to specialize 'expected<>'=20
> for `exception_ptr` because it does something different. Additional=20
> traits only make this feeling stronger that you will be trying to pack=20
> two different things into the same name -- somewhat artificially. It=20
> looks that with traits/policies you can stuff two absolutely unrelated=20
> types into one template. Of course in your case they are not=20
> absolutely different, but also the differences are not trivial. Andrei=20
> Alexandrescu, it seems, only considered the exception_ptr case and it=20
> made sense because for this case lots of problems becomes trivial to=20
> solve (e.g., you know what value() should do).
>
> And this particular problem aside, adding to many parameters is a=20
> problem on its own. You are not standardizing one type anymore, but a=20
> series of types potentially incompatible with one another. Will they=20
> be convertible to one another? Who will decide which policy to use?=20
> The implementer of the function or the caller. What if they have=20
> different preferences? Will I need to translate one expected<> to=20
> another? There will be different types floating around -- this is=20
> somewhat opposite to standardizing one. Consider shared_ptr. Its=20
> deleter type is erased so that there is only one shared_ptr type (for=20
> a given T).
>
> Regards,
> &rzej
> --=20
>
IMHO expected<T, E> and expected<T, exception_ptr> doesn't differ in=20
that many ways, the policy has only 2 static functions and it is enough=20
to emulate Alexandrescu class if we want to. Maybe it looks like we=20
extracted two unrelated concepts in one trait, however it's related to=20
expected but is it enough?

About the type erasure, it adds an unnecessary pointer since the trait=20
will not carry data. At some point, I implemented expected<T, E, Traits>=20
such that expected<T, E, Traits1> and expected<T, E, Traits2> were fully=20
compatible. Deleters and allocators policies modify the structure of an=20
object, expected_traits will never alter it. This brings me to another=20
general question:

Does a class parametrized by a *behavioral* policy should be implicitly=20
convertible to the same class parametrized by a policy of a different type?

Thanks for the interesting comments,
Pierre Talbot

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

--------------010109000901050804000807
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">
    <br>
    <div class=3D"moz-cite-prefix">Le 25/06/2014 09:55, Andrzej
      Krzemie=C5=84ski a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:8ef24514-599b-421d-b2d8-83ae64bc650d@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=BCytkownik Pierr=
e
        Talbot napisa=C5=82:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi,
          <br>
          <br>
          I'd like to discuss the section 7.2 of the proposal N4015
          (adding a <br>
          class expected&lt;T,E&gt;). It adds a trait to expected, so
          the type becomes <br>
          expected&lt;T,E,Traits&gt;. It enables custom behavior in the
          value() method <br>
          in case an error is contained. For the moment, it launches a <br>
          bad_expected_access, but we might like to launch the contained
          exception <br>
          if E=3D=3Dstd::exception_ptr or std::system_error if
          E=3D=3Dstd::error_code. Or <br>
          maybe even assert(false).
          <br>
          <br>
          Secondly, in the monadic methods (bind/then/map), the
          continuation can <br>
          throw an exception and we think it could be useful to
          customize the <br>
          behavior, for example we might want to catch and store the
          exception. <br>
          Follow a specialization of expected_traits for error_code:
          <br>
          <br>
          template &lt;class T&gt;
          <br>
          struct expected_traits&lt;expected&lt;T, error_code&gt;&gt;
          <br>
          {
          <br>
          =C2=A0 =C2=A0static expected&lt;T, error_code&gt;
          catch_exception(exception_ptr e)
          <br>
          =C2=A0 =C2=A0{
          <br>
          =C2=A0 =C2=A0 =C2=A0try{
          <br>
          =C2=A0 =C2=A0 =C2=A0 =C2=A0rethrow_exception(e);
          <br>
          =C2=A0 =C2=A0 =C2=A0} catch(const system_error&amp; e) {
          <br>
          =C2=A0 =C2=A0 =C2=A0 =C2=A0return make_unexpected(e.code());
          <br>
          =C2=A0 =C2=A0 =C2=A0}
          <br>
          =C2=A0 =C2=A0}
          <br>
          <br>
          =C2=A0 =C2=A0static void bad_access(error_code e)
          <br>
          =C2=A0 =C2=A0{
          <br>
          =C2=A0 =C2=A0 =C2=A0throw system_error(e);
          <br>
          =C2=A0 =C2=A0}
          <br>
          };
          <br>
          <br>
          Note that this trait would help people to interact with
          exception-style <br>
          code while keeping some guarantees about the exception safety.
          Also, a <br>
          default expected_traits is provided and mimics the current
          behavior <br>
          (throwing bad_expected_access and don't catch exception thrown
          by <br>
          continuation).
          <br>
          <br>
          Do you think it worth adding a third template argument to
          expected for <br>
          this purpose?
          <br>
        </blockquote>
        <div><br>
          This dilemma brings me to section 7.8 of the proposal: <br>
          "As the behavior of expected&lt;E,T&gt; and
          expected&lt;exception_ptr,T&gt; differs in a lot of points (at
          least currently), should expected&lt;E,T&gt; and
          expected&lt;exception_ptr,T&gt; be represented by two
          different classes?"<br>
          <br>
          Even w/o this dilemma you already propose to specialize
          'expected&lt;&gt;' for `exception_ptr` because it does
          something different. Additional traits only make this feeling
          stronger that you will be trying to pack two different things
          into the same name -- somewhat artificially. It looks that
          with traits/policies you can stuff two absolutely unrelated
          types into one template. Of course in your case they are not
          absolutely different, but also the differences are not
          trivial. Andrei Alexandrescu, it seems, only considered the
          exception_ptr case and it made sense because for this case
          lots of problems becomes trivial to solve (e.g., you know what
          value() should do).<br>
          <br>
          And this particular problem aside, adding to many parameters
          is a problem on its own. You are not standardizing one type
          anymore, but a series of types potentially incompatible with
          one another. Will they be convertible to one another? Who will
          decide which policy to use? The implementer of the function or
          the caller. What if they have different preferences? Will I
          need to translate one expected&lt;&gt; to another? There will
          be different types floating around -- this is somewhat
          opposite to standardizing one. Consider shared_ptr. Its
          deleter type is erased so that there is only one shared_ptr
          type (for a given T).<br>
          <br>
          Regards,<br>
          &amp;rzej<br>
        </div>
      </div>
      -- <br>
      <br>
    </blockquote>
    IMHO expected&lt;T, E&gt; and expected&lt;T, exception_ptr&gt;
    doesn't differ in that many ways, the policy has only 2 static
    functions and it is enough to emulate Alexandrescu class if we want
    to. Maybe it looks like we extracted two unrelated concepts in one
    trait, however it's related to expected but is it enough?<br>
    <br>
    About the type erasure, it adds an unnecessary pointer since the
    trait will not carry data. At some point, I implemented
    expected&lt;T, E, Traits&gt; such that expected&lt;T, E, Traits1&gt;
    and expected&lt;T, E, Traits2&gt; were fully compatible. Deleters
    and allocators policies modify the structure of an object,
    expected_traits will never alter it. This brings me to another
    general question:<br>
    <br>
    Does a class parametrized by a *behavioral* policy should be
    implicitly convertible to the same class parametrized by a policy of
    a different type?<br>
    <br>
    Thanks for the interesting comments,<br>
    Pierre Talbot<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 />

--------------010109000901050804000807--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 25 Jun 2014 06:31:07 -0700 (PDT)
Raw View
------=_Part_320_24993989.1403703068085
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



W dniu =C5=9Broda, 25 czerwca 2014 14:34:48 UTC+2 u=C5=BCytkownik Pierre Ta=
lbot=20
napisa=C5=82:
>
> =20
> Le 25/06/2014 09:55, Andrzej Krzemie=C5=84ski a =C3=A9crit :
> =20
>
>
> W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=BCytkownik Pierre Talb=
ot=20
> napisa=C5=82:=20
>>
>> Hi,=20
>>
>> I'd like to discuss the section 7.2 of the proposal N4015 (adding a=20
>> class expected<T,E>). It adds a trait to expected, so the type becomes=
=20
>> expected<T,E,Traits>. It enables custom behavior in the value() method=
=20
>> in case an error is contained. For the moment, it launches a=20
>> bad_expected_access, but we might like to launch the contained exception=
=20
>> if E=3D=3Dstd::exception_ptr or std::system_error if E=3D=3Dstd::error_c=
ode. Or=20
>> maybe even assert(false).=20
>>
>> Secondly, in the monadic methods (bind/then/map), the continuation can=
=20
>> throw an exception and we think it could be useful to customize the=20
>> behavior, for example we might want to catch and store the exception.=20
>> Follow a specialization of expected_traits for error_code:=20
>>
>> template <class T>=20
>> struct expected_traits<expected<T, error_code>>=20
>> {=20
>>    static expected<T, error_code> catch_exception(exception_ptr e)=20
>>    {=20
>>      try{=20
>>        rethrow_exception(e);=20
>>      } catch(const system_error& e) {=20
>>        return make_unexpected(e.code());=20
>>      }=20
>>    }=20
>>
>>    static void bad_access(error_code e)=20
>>    {=20
>>      throw system_error(e);=20
>>    }=20
>> };=20
>>
>> Note that this trait would help people to interact with exception-style=
=20
>> code while keeping some guarantees about the exception safety. Also, a=
=20
>> default expected_traits is provided and mimics the current behavior=20
>> (throwing bad_expected_access and don't catch exception thrown by=20
>> continuation).=20
>>
>> Do you think it worth adding a third template argument to expected for=
=20
>> this purpose?=20
>>
>
> This dilemma brings me to section 7.8 of the proposal:=20
> "As the behavior of expected<E,T> and expected<exception_ptr,T> differs i=
n=20
> a lot of points (at least currently), should expected<E,T> and=20
> expected<exception_ptr,T> be represented by two different classes?"
>
> Even w/o this dilemma you already propose to specialize 'expected<>' for=
=20
> `exception_ptr` because it does something different. Additional traits on=
ly=20
> make this feeling stronger that you will be trying to pack two different=
=20
> things into the same name -- somewhat artificially. It looks that with=20
> traits/policies you can stuff two absolutely unrelated types into one=20
> template. Of course in your case they are not absolutely different, but=
=20
> also the differences are not trivial. Andrei Alexandrescu, it seems, only=
=20
> considered the exception_ptr case and it made sense because for this case=
=20
> lots of problems becomes trivial to solve (e.g., you know what value()=20
> should do).
>
> And this particular problem aside, adding to many parameters is a problem=
=20
> on its own. You are not standardizing one type anymore, but a series of=
=20
> types potentially incompatible with one another. Will they be convertible=
=20
> to one another? Who will decide which policy to use? The implementer of t=
he=20
> function or the caller. What if they have different preferences? Will I=
=20
> need to translate one expected<> to another? There will be different type=
s=20
> floating around -- this is somewhat opposite to standardizing one. Consid=
er=20
> shared_ptr. Its deleter type is erased so that there is only one shared_p=
tr=20
> type (for a given T).
>
> Regards,
> &rzej
>  --=20
>
>  IMHO expected<T, E> and expected<T, exception_ptr> doesn't differ in tha=
t=20
> many ways, the policy has only 2 static functions and it is enough to=20
> emulate Alexandrescu class if we want to. Maybe it looks like we extracte=
d=20
> two unrelated concepts in one trait, however it's related to expected but=
=20
> is it enough?
>

I do not know. Note that if you add a third function to the trait: how=20
should the default constructor behave, you can fit std::optional into=20
expected<>. I am not trying to prove anything. It is just an observation.
=20

>
> About the type erasure, it adds an unnecessary pointer since the trait=20
> will not carry data. At some point, I implemented expected<T, E, Traits>=
=20
> such that expected<T, E, Traits1> and expected<T, E, Traits2> were fully=
=20
> compatible. Deleters and allocators policies modify the structure of an=
=20
> object, expected_traits will never alter it. This brings me to another=20
> general question:
>
> Does a class parametrized by a *behavioral* policy should be implicitly=
=20
> convertible to the same class parametrized by a policy of a different typ=
e?
>

Note that even if you make them implicitly convertible, a number of=20
performance improvements like copy elision and implicit move in return=20
statement will be lost.=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_320_24993989.1403703068085
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>W dniu =C5=9Broda, 25 czerwca 2014 14:34:48 UTC+2 =
u=C5=BCytkownik Pierre Talbot napisa=C5=82:<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">
    <br>
    <div>Le 25/06/2014 09:55, Andrzej
      Krzemie=C5=84ski a =C3=A9crit&nbsp;:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        W dniu wtorek, 24 czerwca 2014 07:01:18 UTC+2 u=C5=BCytkownik Pierr=
e
        Talbot napisa=C5=82:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">Hi,
          <br>
          <br>
          I'd like to discuss the section 7.2 of the proposal N4015
          (adding a <br>
          class expected&lt;T,E&gt;). It adds a trait to expected, so
          the type becomes <br>
          expected&lt;T,E,Traits&gt;. It enables custom behavior in the
          value() method <br>
          in case an error is contained. For the moment, it launches a <br>
          bad_expected_access, but we might like to launch the contained
          exception <br>
          if E=3D=3Dstd::exception_ptr or std::system_error if
          E=3D=3Dstd::error_code. Or <br>
          maybe even assert(false).
          <br>
          <br>
          Secondly, in the monadic methods (bind/then/map), the
          continuation can <br>
          throw an exception and we think it could be useful to
          customize the <br>
          behavior, for example we might want to catch and store the
          exception. <br>
          Follow a specialization of expected_traits for error_code:
          <br>
          <br>
          template &lt;class T&gt;
          <br>
          struct expected_traits&lt;expected&lt;T, error_code&gt;&gt;
          <br>
          {
          <br>
          &nbsp; &nbsp;static expected&lt;T, error_code&gt;
          catch_exception(exception_ptr e)
          <br>
          &nbsp; &nbsp;{
          <br>
          &nbsp; &nbsp; &nbsp;try{
          <br>
          &nbsp; &nbsp; &nbsp; &nbsp;rethrow_exception(e);
          <br>
          &nbsp; &nbsp; &nbsp;} catch(const system_error&amp; e) {
          <br>
          &nbsp; &nbsp; &nbsp; &nbsp;return make_unexpected(e.code());
          <br>
          &nbsp; &nbsp; &nbsp;}
          <br>
          &nbsp; &nbsp;}
          <br>
          <br>
          &nbsp; &nbsp;static void bad_access(error_code e)
          <br>
          &nbsp; &nbsp;{
          <br>
          &nbsp; &nbsp; &nbsp;throw system_error(e);
          <br>
          &nbsp; &nbsp;}
          <br>
          };
          <br>
          <br>
          Note that this trait would help people to interact with
          exception-style <br>
          code while keeping some guarantees about the exception safety.
          Also, a <br>
          default expected_traits is provided and mimics the current
          behavior <br>
          (throwing bad_expected_access and don't catch exception thrown
          by <br>
          continuation).
          <br>
          <br>
          Do you think it worth adding a third template argument to
          expected for <br>
          this purpose?
          <br>
        </blockquote>
        <div><br>
          This dilemma brings me to section 7.8 of the proposal: <br>
          "As the behavior of expected&lt;E,T&gt; and
          expected&lt;exception_ptr,T&gt; differs in a lot of points (at
          least currently), should expected&lt;E,T&gt; and
          expected&lt;exception_ptr,T&gt; be represented by two
          different classes?"<br>
          <br>
          Even w/o this dilemma you already propose to specialize
          'expected&lt;&gt;' for `exception_ptr` because it does
          something different. Additional traits only make this feeling
          stronger that you will be trying to pack two different things
          into the same name -- somewhat artificially. It looks that
          with traits/policies you can stuff two absolutely unrelated
          types into one template. Of course in your case they are not
          absolutely different, but also the differences are not
          trivial. Andrei Alexandrescu, it seems, only considered the
          exception_ptr case and it made sense because for this case
          lots of problems becomes trivial to solve (e.g., you know what
          value() should do).<br>
          <br>
          And this particular problem aside, adding to many parameters
          is a problem on its own. You are not standardizing one type
          anymore, but a series of types potentially incompatible with
          one another. Will they be convertible to one another? Who will
          decide which policy to use? The implementer of the function or
          the caller. What if they have different preferences? Will I
          need to translate one expected&lt;&gt; to another? There will
          be different types floating around -- this is somewhat
          opposite to standardizing one. Consider shared_ptr. Its
          deleter type is erased so that there is only one shared_ptr
          type (for a given T).<br>
          <br>
          Regards,<br>
          &amp;rzej<br>
        </div>
      </div>
      -- <br>
      <br>
    </blockquote>
    IMHO expected&lt;T, E&gt; and expected&lt;T, exception_ptr&gt;
    doesn't differ in that many ways, the policy has only 2 static
    functions and it is enough to emulate Alexandrescu class if we want
    to. Maybe it looks like we extracted two unrelated concepts in one
    trait, however it's related to expected but is it enough?<br></div></bl=
ockquote><div><br>I do not know. Note that if you add a third function to t=
he trait: how should the default constructor behave, you can fit std::optio=
nal into expected&lt;&gt;. I am not trying to prove anything. It is just an=
 observation.<br>&nbsp;<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">
    <br>
    About the type erasure, it adds an unnecessary pointer since the
    trait will not carry data. At some point, I implemented
    expected&lt;T, E, Traits&gt; such that expected&lt;T, E, Traits1&gt;
    and expected&lt;T, E, Traits2&gt; were fully compatible. Deleters
    and allocators policies modify the structure of an object,
    expected_traits will never alter it. This brings me to another
    general question:<br>
    <br>
    Does a class parametrized by a *behavioral* policy should be
    implicitly convertible to the same class parametrized by a policy of
    a different type?<br></div></blockquote><div><br>Note that even if you =
make them implicitly convertible, a number of performance improvements like=
 copy elision and implicit move in return statement will be lost. <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_320_24993989.1403703068085--

.