Subject: Re: [boost] [next gen futures] Lightweight monad ready for inspection
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-06-21 03:07:11


Le 19/06/15 19:03, Niall Douglas a écrit :
> Some may remember the thread starting from
> http://boost.2283326.n4.nabble.com/next-gen-future-promise-What-to-cal
> l-the-monadic-return-type-td4676039.html and that I would firstly
> prepare an optimally lightweight monad<T> for review here before
> going on to base a next-gen lightweight future-promise on that
> monad<T>.

Nial, I don't understand why you call this class monad. I see it much
more as a generalized optional_expected that allows the user to say
which exception is thorw when there is an error type and not an
exception type.

IMO, the last parameter throw_error is really not needed.

You can always wrap an error code with a class that states how to throw
an exception. That means that we need an additional Error concept that
defines the throw_error function, e.g.

We could have a class that wraps an error with an exception

template <class Error, class Exception>
struct ThrowError {
      Error value;
};

template <class Error, class Exception>
void throw_error(ThrowError<Error, Exception> const& e) {
     throw Exception(e.value);
}

Now the generalized optional/expected class will use the throw error
whenever it needs to throw an exception and has an error type stored.

BTW, why have you chosen a Callable for throw_error instead of directly
the Exception?

BTH, expected could already store an error or an exception_ptr. All you
need is to have a class

template <class Error, class Exception>
struct ErrorOrException;

Resuming you monad class is in some way an alias of

     expected<optional<R>, ErrorOrException<ThrowError<Error,
ThrowException>, Exception>>

possibly optimized with a specific specialization.

BTW, why your class accepts only on Exception type and not a variadic
set of Exceptions types?

I have some trouble with the is_ready function. You say "True if monad
is not empty.".
Do you mean that oi will not be ready

optional<int> oi;

You need to add the preconditions of each function. No precondition mean
the function is not partial.

I don't see comparison operators, neither hash customization, was this
intentional?

I suspect that the exception thown by value() when an instance is empty
is not future_error<no_state>,and that there is a type on the
documentation. Or was this intentional?

In the function value()&& you say
"If contains a value_type, returns a rvalue reference to it, else throws
an exception of future_error(no_state), system_error or the
exception_type."

Why system_error? Do you mean that when the exception_type given as
parameter is exception_ptr, the exception throw is exception_ptr and not
the stored exception? In the Expected proposal and in std::future, the
exception throw will be the stored exception.

The function has_exception is not coherent with the others state
observer functions empty/has/value/has_error.

What is the exact signature (or valid signatures) of the functions
passed to map/bind/then?
BTW, are these functions proposed?

Last can the map function be applied to an empty instance? What would be
the result?

Best,
Vicente