This seams to be implying something opposite: that empty can can be treated as less abnormal than error.
You're forgetting locality. Locally to the find loop, the valued or errored state returned by something() is the normal situation and you don't care which it returns. Locally to the find loop, failing to find what we are looking for is the abnormal situation. The programmer looking at the find loop won't be thinking in terms of errors or success of something(), but rather that the flow of execution in the find loop is correct or incorrect. I really should emphasise that this stuff, when used in practice, is nothing like as complicated as this thread of discussion is making it seem. Any programmer, even an undergrad, will look at that find loop and know exactly what it means and how it works intuitively.
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 "abnormally empty"
Am I right? If so, maybe you need two separate states "simply no T" and "abnormal situation"?
Empty is *defaulted* to the most abnormal state by Outcome's default semantics. So if you call .error() on a valued Outcome, you get back a default constructed error type, no exception thrown. Same goes for .exception(). But if you call .error() or .exception() on an empty Outcome, you *always* get an exception thrown. Therefore, if you write your Outcome using code without state checks before observation i.e. you call .error() without checking .has_error() beforehand, you get a stronger, more abortive default action than if the Outcome were errored, valued or excepted. You the programmer may wish to avoid the default actions, in which case you check state before access. You can then manually specify any other action you prefer. The "more abnormal" solely refers to my design choice of default semantics only for the empty state. Reviewers may think those choices misguided or plain wrong, and might suggest better default semantics. For example, some might feel that any time one tries to observe state where the state is different, you should always throw an exception. That would be a very conservative design choice and I'd disagree with it. But I would understand the rationale. I would also add that it is trivial to wrap an Outcome with replacement observer functions which change the default actions, or to customise the policy class to have different defaults. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/