Boost logo

Boost :

Subject: Re: [boost] Interest in an 'either' library?
From: David Sankel (camior_at_[hidden])
Date: 2013-06-26 11:48:07


On Tue, Jun 25, 2013 at 8:27 AM, Larry Evans <cppljevans_at_[hidden]>wrote:

> On 06/24/13 22:55, David Sankel wrote:
> > On Mon, Jun 24, 2013 at 1:19 PM, Eric Niebler <eniebler_at_[hidden]>
> wrote:
> >
> >> On 13-06-24 11:53 AM, Pierre Talbot wrote:
> >>>>
> >>>> This misses what is, IMO, the most important use case of Haskell's
> >>>> Either monad: automatic error propagation. This would be more useful
> if
> >>>> there were a way to call a function such that if any of the function's
> >>>> arguments were an Either-in-error, the function would immediately
> return
> >>>> the error.
> >>>>
> >>>> I implemented something like this. Check out substitution_failure and
> >>>> try_call starting here:
> >>>>
> >>>>
> >>
> https://github.com/ericniebler/proto-0x/blob/master/boost/proto/v5/utility.hpp#L742
> >>>
> >>> In the Expected proposal, there are some methods related to this idea.
> >>
> >>
> > <snip various do-syntax derivatives>
> >
> > If we really care about adding a do syntax EDSL, why not make it general
> > purpose like Haskell's version so that it can work with any monad and
> > compose better with other things?
> >
> > either<error, int> result =
> > do(
> > set( _x, getInt ),
> > set( _y, getInt ),
> > doReturn( pure( _x + _y ) ) );
> >
> > If we're going to do that, lets do it generically and completely.
> >
> >
> +1
>
> David, is there source code demonstrating this do syntax?
>

I haven't made a library. That was off the top of my head.

> Could you show how to do Eric's example with this do syntax?
>

Eric's example was:

    // if h or g fails, h return immediately.
    try_call(h)(f(), "hello world", g(), 42);

Using do syntax, something like...

do(
  set( _fResult, f ),
  set( _gResult, g ),
  doReturn( app( h, _fResult, "hello world", _gResult, 42 ) ) );

Well, actually this improves efficiency, if f has an 'error' then g won't
be evaluated.

But, the more I think of this, the more I think something like indices
would work very well here. _1 would refer to the result of the first
statement, _2 the result of the second, etc. I also prefer the 'pure'
moniker instead of 'return' for taking a non-wrapped value and putting it
into a wrapped one.

do(
  app( f ),
  app( g ),
  pure( app( h, _1, "hello world", _2, 42 ) ) );

This works with the following:

either<Error, A> f();
either<Error, B> g();
C h( A, std::string, B, int );

But would also work with,

optional< A> f();
optional< B> g();
C h( A, std::string, B, int );


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk