Boost logo

Boost :

Subject: Re: [boost] Boost.Outcome review - First questions
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-23 15:19:26


>> But you might be onto something. Some other combination with
>> value_or() might well produce a reference to a deleted temporary. That
>> would explain the choice of value returning semantics for value_or().
>
> Having value_or at all is wrong. expected shouldn't have it. It
> encourages people to drop the error code on the floor.

I really don't think it does. I've certainly never felt encouraged to do
that. I use .value_or() mostly in constexpr or functional use cases. I
don't think I've ever used it outside those. But then I don't believe in
artificially constraining users unless it's really bad for their health.
I give them what they (think they) want.

> expected does give you the reason. This reason should be acknowledged,
> not ignored or silently dropped.

Back at the beginning when designing Outcome, one of my design ideas was
a variety which called std::terminate on destruction if an error had
never been retrieved. So, the idea behind this family of Outcomes was
that they were "single shot", .error() and .value() could be called
exactly once after which the outcome became empty. On destruction, if an
error had never been retrieved, it was fatal exit time.

I never found a use for that particular variety in my own code, but I
find the semantics very attractive. They impose rigour. I just wish I
could make the statically obvious failure to collect state a compile
time instead of runtime error.

I could be very easily persuaded to go ahead and add that variety
(recommended naming is welcomed!).

> This is but one example in which "consistency" (in this case between
> optional and expected) makes an interface worse. These two are different
> things, they shouldn't be consistent. op->? Really?
>
> This is also why I don't care much for Niall's decision to include
> option<T> in his library, with the consequent bubbling up of option's
> properties (such as the ability to have an empty state) upwards into
> result/outcome.

You are wrong that the option<T> => anything emptiness preservation was
a motivation of mine.

I was far more motivated by the power of the state of "empty" to
simplify end user code. For example, the example above or the for loop
examples I've mentioned before. If one were to implement the rigorous
outcomes described above, you'd have implicit conversion from any less
rigorous outcome to any more rigorous outcome, but require explicit
conversion in the opposite direction.

> Sure, now that one has the empty state, one can make it do something
> useful, such as make error() throw when empty, so that its utility
> becomes a self-fulfilling prophecy. But it shouldn't be there.
> result/outcome would be cleaner and more elegant without option and the
> empty state (and result<T> could be brought as close as possible to
> expected<T, error_code>, an equivalence everyone expects.)

Would you still say the above after considering my idea for a family of
"rigorous" outcomes?

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

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