Topic: MonadError interface (was Null coalescing operator)
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 13 May 2017 20:34:06 +0200
Raw View
This is a multi-part message in MIME format.
--------------FC8E4C0688A32FE9DED04010
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable
Hi,
I've preferred to fork this thread as it goes beyond the PO concerns.
Le 12/05/2017 =C3=A0 13:07, dgutson . a =C3=A9crit :
>
>
> El 11/5/2017 18:19, <philippe.groarke@gmail.com=20
> <mailto:philippe.groarke@gmail.com>> escribi=C3=B3:
>
> I've decided to dip my toe into the standardization process. As
> such, I've come up with (what I think is) a small feature I really
> like. I have to do a lot of programming in [other language] at
> work, and something I greatly miss when getting back to C++ is the
> null coalescing operator. It is a quality of life feature that
> simplifies and compacts patterns of code that are used throughout
> codebases.
>
> Consider the following conditional operator use case:
>
> |
> Test*get_test(){/*...*/}
>
> Test*test =3D(get_test()!=3Dnullptr)?get_test():newTest();
> |
>
>
> If `get_test()` has side effects, we may have a problem. We would
> use the following instead.
>
> |
> Test*test =3Dget_test();
> test =3Dtest !=3Dnullptr?test :newTest();
> |
>
>
> We could instead use a shortcut without side effect, the null
> coalescing operator ??.
> The left hand side expression is evaluated and compared to
> nullptr. If it is not nullptr, the evaluation is complete. If it
> is nullptr, the right hand side expression is evaluated.
>
> |
> Test*test =3Dget_test()??newTest();
> |
>
>
> It can also be a concise way to throw on a null value.
>
> |
> some_pointer ??throwstd::invalid_argument("some_pointer is null.");
> |
>
>
>
> What about a library function such as
>
> template <class T, class Func>
> T* coalesce(T* x, Func f)
> {
> if (x =3D=3D nullptr)
> return f();
> else
> return x;
> }
>
> So coalesce(x, [](){return new T;}) or also the throw use case.
> ?
>
>
The coalesce function behaves as the MonadError catch_error function
auto catch_error(M, (E->M)) -> M;
but the single error case for a pointer is when the pointer is null, so=20
no need to have a parameter in this case.
auto catch_error(T*, (void->T*)) -> T*;
We could consider optional<T> and T* (and smart pointers) as monad=20
errors. optional<T> and T* (and smart pointers) could either have void=20
as error type or have nullopt_t and nullptr_t respectively.
I've mapped Nullable (as optional<T> and pointers) as models of=20
MonadError with an obvious void error_type.
While it could support T*, raw pointers could have management issues=20
that I have not tried to address. I believe people should use smart=20
pointers in their applications.
Vicente
P.S. I expect to have ready a *basic* proposal for a monadic interface=20
with customization points for Toronto.
A very first draft containing something more than an incomplete=20
reference is located at
https://github.com/viboes/std-make/blob/master/doc/proposal/monads/Monads.m=
d
You can take a look at the implementation at
https://github.com/viboes/std-make/blob/master/include/experimental/fundame=
ntal/v3/monad_error
https://github.com/viboes/std-make/blob/master/include/experimental/fundame=
ntal/v3/monad
https://github.com/viboes/std-make/blob/master/include/experimental/fundame=
ntal/v3/applicative
https://github.com/viboes/std-make/blob/master/include/experimental/fundame=
ntal/v3/functor
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f3674877-a689-b3f9-f11e-ec8ff1bdf087%40wanadoo.f=
r.
--------------FC8E4C0688A32FE9DED04010
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 bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Hi,<br>
<br>
I've preferred to fork this thread as it goes beyond the PO
concerns. <br>
<br>
Le 12/05/2017 =C3=A0 13:07, dgutson . a =C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:CAFdMc-12pufc96=3DQJwL6HcJ8hZHWpeL7V_zGtooD0OwWW4h0kw@mail.gmai=
l.com"
type=3D"cite">
<div dir=3D"auto">
<div><br>
<div class=3D"gmail_extra"><br>
<div class=3D"gmail_quote">El 11/5/2017 18:19, <<a
moz-do-not-send=3D"true"
href=3D"mailto:philippe.groarke@gmail.com">philippe.groarke=
@gmail.com</a>>
escribi=C3=B3:<br type=3D"attribution">
<blockquote class=3D"quote" style=3D"margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">
<div>
<div>I've decided to dip my toe into the
standardization process. As such, I've come up
with (what I think is) a small feature I really
like. I have to do a lot of programming in [other
language] at work, and something I greatly miss
when getting back to C++ is the null coalescing
operator. It is a quality of life feature that
simplifies and compacts patterns of code that are
used throughout codebases.</div>
<div><br>
</div>
<div>Consider the following conditional operator use
case:</div>
<div><br>
</div>
<div class=3D"m_-2827024602115319900prettyprint"
style=3D"background-color:rgb(250,250,250);border:1px
solid rgb(187,187,187);word-wrap:break-word"><code
class=3D"m_-2827024602115319900prettyprint">
<div
class=3D"m_-2827024602115319900subprettyprint"><s=
pan
style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">*</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
get_test</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">()</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">{</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span
style=3D"color:rgb(136,0,0);font-family:Arial,H=
elvetica,sans-serif"><span
style=3D"color:#800"
class=3D"m_-2827024602115319900styled-by-pret=
tify">/*...*/</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">}</span></span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy"><br>
<br>
</span><span style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">*</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">(</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">get_test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">()</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">!=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">nullptr</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">)</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">?</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
get_test</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">()</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">:</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">new</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">();</span></div>
</code></div>
<div><br>
</div>
<div><br>
</div>
<div>If `get_test()`=C2=A0has side effects, we may have=
a
problem. We would use the following instead.</div>
<div><br>
</div>
<div class=3D"m_-2827024602115319900prettyprint"
style=3D"background-color:rgb(250,250,250);border:1px
solid rgb(187,187,187);word-wrap:break-word"><code
class=3D"m_-2827024602115319900prettyprint">
<div
class=3D"m_-2827024602115319900subprettyprint"><s=
pan
style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">*</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
get_test</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">();</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy"><br>
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">!=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">nullptr</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">?</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">:</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">new</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">
</span><span style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pretti=
fy">();</span></div>
</code></div>
<div><br>
</div>
<div><br>
</div>
<div>We could instead use a shortcut without side
effect, the null coalescing operator ??.=C2=A0</div>
<div>The left hand side expression is evaluated and
compared to nullptr. If it is not nullptr, the
evaluation is complete. If it is nullptr, the
right hand side expression is evaluated.</div>
<div><br>
</div>
<div>
<div class=3D"m_-2827024602115319900prettyprint"
style=3D"background-color:rgb(250,250,250);border:1=
px
solid rgb(187,187,187);word-wrap:break-word"><code
class=3D"m_-2827024602115319900prettyprint">
<div
class=3D"m_-2827024602115319900subprettyprint">=
<span
style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pret=
tify">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">*</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
test </span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">=3D</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
get_test</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">()</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">??</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pret=
tify">new</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
</span><span style=3D"color:#606"
class=3D"m_-2827024602115319900styled-by-pret=
tify">Test</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">();</span></div>
</code></div>
<br>
</div>
<div><br>
</div>
<div>It can also be a concise way to throw on a null
value.</div>
<div><br>
</div>
<div>
<div class=3D"m_-2827024602115319900prettyprint"
style=3D"background-color:rgb(250,250,250);border:1=
px
solid rgb(187,187,187);word-wrap:break-word"><code
class=3D"m_-2827024602115319900prettyprint">
<div
class=3D"m_-2827024602115319900subprettyprint">=
<span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">some_pointer
</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">??</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
</span><span style=3D"color:#008"
class=3D"m_-2827024602115319900styled-by-pret=
tify">throw</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">
std</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">::</span><span
style=3D"color:#000"
class=3D"m_-2827024602115319900styled-by-pret=
tify">invalid_argument</span><span
style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">(</span><span
style=3D"color:#080"
class=3D"m_-2827024602115319900styled-by-pret=
tify">"some_<wbr>pointer
is null."</span><span style=3D"color:#660"
class=3D"m_-2827024602115319900styled-by-pret=
tify">);</span></div>
</code></div>
<br>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
<div dir=3D"auto"><br>
</div>
<div dir=3D"auto"><br>
</div>
<div dir=3D"auto">What about a library function such as</div>
<div dir=3D"auto"><br>
</div>
<div dir=3D"auto">template <class T, class Func></div>
<div dir=3D"auto">T* coalesce(T* x, Func f)</div>
<div dir=3D"auto">{</div>
<div dir=3D"auto">=C2=A0 =C2=A0 =C2=A0if (x =3D=3D nullptr)</div>
<div dir=3D"auto">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return f=
();</div>
<div dir=3D"auto">=C2=A0 =C2=A0 =C2=A0else</div>
<div dir=3D"auto">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return x=
;</div>
<div dir=3D"auto">}</div>
<div dir=3D"auto"><br>
</div>
<div dir=3D"auto">So coalesce(x, [](){return new T;}) =C2=A0 or als=
o
the throw use case.</div>
<div dir=3D"auto">?</div>
<div dir=3D"auto"><br>
</div>
<div dir=3D"auto">
<div class=3D"gmail_extra">
<div class=3D"gmail_quote">
<blockquote class=3D"quote" style=3D"margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">
<div>
<div><br>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
<br>
The coalesce function behaves as the MonadError catch_error function<br=
>
<br>
=C2=A0=C2=A0=C2=A0 auto catch_error(M, (E->M)) -> M;<br>
<br>
but the single error case for a pointer is when the pointer is null,
so no need to have a parameter in this case.<br>
<br>
=C2=A0=C2=A0=C2=A0 auto catch_error(T*, (void->T*)) -> T*;<br>
<br>
We could consider optional<T> and T* (and smart pointers) as
monad errors. optional<T> and T* (and smart pointers) could
either have void as error type or have nullopt_t and nullptr_t
respectively. <br>
I've mapped Nullable (as optional<T> and=C2=A0 pointers) as model=
s
of MonadError with an obvious void error_type.<br>
<br>
While it could support T*, raw pointers could have management issues
that I have not tried to address. I believe people should use smart
pointers in their applications.<br>
<br>
Vicente<br>
<br>
P.S. I expect to have ready a *basic* proposal for a monadic
interface with customization points for Toronto.<br>
A very first draft containing something more than an incomplete
reference is located at<br>
=C2=A0=C2=A0=C2=A0
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/st=
d-make/blob/master/doc/proposal/monads/Monads.md">https://github.com/viboes=
/std-make/blob/master/doc/proposal/monads/Monads.md</a><br>
<br>
You can take a look at the implementation at=C2=A0 <br>
=C2=A0=C2=A0=C2=A0
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/include/experimental/fundamental/v3/monad_error">https://git=
hub.com/viboes/std-make/blob/master/include/experimental/fundamental/v3/mon=
ad_error</a><br>
=C2=A0=C2=A0=C2=A0
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/include/experimental/fundamental/v3/monad">https://github.co=
m/viboes/std-make/blob/master/include/experimental/fundamental/v3/monad</a>=
<br>
=C2=A0=C2=A0=C2=A0
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/include/experimental/fundamental/v3/applicative">https://git=
hub.com/viboes/std-make/blob/master/include/experimental/fundamental/v3/app=
licative</a><br>
=C2=A0=C2=A0=C2=A0
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/include/experimental/fundamental/v3/functor">https://github.=
com/viboes/std-make/blob/master/include/experimental/fundamental/v3/functor=
</a><br>
<br>
<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f3674877-a689-b3f9-f11e-ec8ff1bdf087%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f3674877-a689-b3f9-f11e-ec8ff1bdf087=
%40wanadoo.fr</a>.<br />
--------------FC8E4C0688A32FE9DED04010--
.