Boost logo

Boost :

Subject: Re: [boost] [outcome] outcome without empty state?
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-28 11:37:55


>> So compare_directories() walks two directory structures using the
>> Filesystem TS and compares them for equivalence using fuzzy criteria.
>> Here we use the empty state to indicate "directory trees are identical",
>> an error state to indicate an error occurred, and a valued state to give
>> the path of the first item which differed.
>>
>
> So, what I am seeing here (correct me if I am wrong), is that conceptually
> (performance considerations excluded) a return type that clearly reflects
> your intentions would be:
>
> ```
> result<optional<filesystem::path>>
> ```
>
> That is:
> * either a path representing the first difference, or
> * no path (but no error) meaning that there was no difference, or
> * information or error that prefvented you from giving the answer

Correct for the example code I gave above.

> But if you used `result<optional<filesystem::path>>` it would be
> suboptimal: you have one discriminator for `result` and one for `optional`.

I don't like typing .value().value(), correct.

> So you applied a "hack": since, result's discriminator can handle one
> additional state fo free, allow it to also represent optional objects. This
> departs from the philosophy you described earlier, that "empty" state is
> the most abnormal of all states.

It's not a hack. The object provides a formal empty state for the
programmer to do with as they wish. So I made use of that feature as it
was intended for the programmer to use. Empty state still has the
strongest, most abnormal default actions, but if you don't write code to
trigger those default actions, then it's just a third state carrying no
payload.

> But all-in-all the code is faster (I think), but what if in some other
> project you find it convenient to return "either a filesystem::path or
> file_desriptor":
>
> ```
> result<variant<filesystem::path, file_descriptor>>
> ```
>
> And again, this is suboptimal, as the result's discriminator could also
> handle two states of the variant's discriminator. Are you going to provide
> yet another "shades" for `result`:
>
> ```
> result_variant<filesystem::path, file_descriptor>
> ```
>
> This is also a useful optimization, but should library handle all possible
> optimizations for particular problems is user's code? I believe users
> should apply such improvements themselves, not via a generic tool.

The difference between the former and the latter is that internal to the
implementation you're always going to have an empty state, at least
under my implementation. So it's a case of choosing to expose it
publicly (result<T>) or not (expected<T>) for programmers to use it
directly, or not.

In other words, it costs the implementation absolutely nothing to expose
the empty state to the public API. So we can provide optional-type
semantics at zero added cost. We could not do that for variant
extensions like you described.

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