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, &lt;<a
                moz-do-not-send=3D"true"
                href=3D"mailto:philippe.groarke@gmail.com">philippe.groarke=
@gmail.com</a>&gt;
              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 &lt;class T, class Func&gt;</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-&gt;M)) -&gt; 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-&gt;T*)) -&gt; T*;<br>
    <br>
    We could consider optional&lt;T&gt; and T* (and smart pointers) as
    monad errors. optional&lt;T&gt; 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&lt;T&gt; 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&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 />
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--

.