Boost logo

Boost :

Subject: Re: [boost] [optional] Safe optional
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2014-11-20 04:29:52


2014-11-19 22:36 GMT+01:00 Vladimir Batov <Vladimir.Batov_at_[hidden]>
:

>
> On 11/20/2014 08:22 AM, Vladimir Batov wrote:
>
>>
>> On 11/19/2014 07:37 PM, Andrzej Krzemienski wrote:
>>
>> ...
>>> optional<double> Aircraft::weight()
>>> {
>>> if (Impl* impl = get_impl())
>>> return impl->compute_weight();
>>> else
>>> return none;
>>> }
>>>
>>> double Aircraft::max_weight()
>>> {
>>> return 10000.0;
>>> }
>>>
>>> bool too_heavy(Aircraft& ac)
>>> {
>>> return ac.weight() > ac.max_weight();
>>> // in "safe" optional compiler would spot the bug
>>> }
>>>
>>
>> There is no bug here! Not from the human perspectives. You are comparing
>> two extremely closely related types! As long as we agree on how "none" is
>> treated, then all kosher. We do compare "ints" with "doubles", don't we? No
>> "safety" concerns.
>>
>
> On the second thought I might probably agree that op<() might be
> questionable... Can we address that differently then?
>

No. Allowing this comparison to work is the right thing to do. It is a
natural consequence of Optional's conceptual model. You should look at
optional<T> as a T plus one additional value, less than any other value.
No-one stops you from adopting any other model (like container of size
0-or-1), but then you are risking that you will be surprised by the result.

Optional is not a container of size 0-or-1. You do not expect an element to
be implicitly converted to its container type.

The source of the confusion in this example above is the wrong expectation
that the compiler will warn you about any place where optional<T> is
confused with T. They are supposed and expected to be confused and mixed.
That's the idea behind implicit conversions.

Yet, many people make this invalid expectation, because what they are
really looking for is something different: something that will detect as
many potential programmer errors as possible (including false positives).

Note that the proposed expected<T, E> has the same "identity crisis":

expected<double, Err> Aircraft::weight()
{
   if (Impl* impl = get_impl())
     return impl->compute_weight();
   else
     return unexpected(some_err);
}

double Aircraft::max_weight()
{
   return 10000.0;
}

bool too_heavy(Aircraft& ac)
{
   return ac.weight() > ac.max_weight();
   // still works!!
}


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