Subject: Re: [boost] [outcome] Ternary logic -- need an example
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-16 08:01:40
2017-05-15 23:42 GMT+02:00 Niall Douglas via Boost <boost_at_[hidden]>:
> >> It doesn't have much to do with tribool. outcome<T> and result<T>
> >> deliberately take a three state based design with an explicit choice of
> >> ternary instead of binary state. The original motivation was actually
> >> for the basic_monad based, since removed, non-allocating future-promise
> >> implementation where we needed a third state to indicate "pending", but
> >> it turned out to be very useful in itself for simplifying usage,
> >> eliminating writing boilerplate, and acting as an out-of-band signalling
> >> mechanism.
> > Ok, so by "ternary" you mean "eihter value, or error, or just nothing".
> It's more than that. Originally before I wrote any code, I drew up the
> design on a whiteboard with the exact semantics for all possible
> permutations of all possible operations based on the three state logic.
> It was there that I decided that the valued state corresponds to ternary
> value TRUE, the errored state corresponds to FALSE, and the empty state
> to OTHER.
> Now that choice is quite controversial. Here on boost-dev we bikeshedded
> that choice for some weeks if I remember correctly. Many felt that empty
> should be FALSE, and errored should be OTHER. But I'm sticking to my
> guns on that, I still think my assignment is the right choice.
> The OTHER state gets treated as truly other, and it's why it gets the
> strongest abort semantics of any of the states. It is considered to be
> the most abnormal of the three possible states by the default actions by
> observer functions.
The above explanation, treated in isolation, makes sense to me: empty is
the most abnormal state. But in the other thread, you say:
But the point being made (badly) in the example above was that you can
> use the empty state to indicate lack of find, and any errored state for
> errors during find etc. So, let me rewrite the above now it's morning
> and I am not babbling incoherently:
> outcome<Foo> found(empty);
> for(auto &i : container)
> auto v = something(i); // returns a result<Foo>
> if(!v.empty()) // if not empty
> found = std::move(v); // auto upconverts preserving error or Foo
> Do something with found.value() ...
This seams to be implying something opposite: that empty can can be treated
as less abnormal than error.
It is my impression that the system of types in Boost.Outcome confuses two
meanings of "empty"
option<T> -- either T or "empty" -- in this case "empty" looks like "just
another state of T", as in boost::optional
result<T> -- either T or an error or "empty" -- in this case it means
Am I right? If so, maybe you need two separate states "simply no T" and