Boost logo

Boost :

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


2014-11-18 7:22 GMT+01:00 Vicente J. Botet Escriba <vicente.botet_at_[hidden]
>:

> Le 17/11/14 10:24, Andrzej Krzemienski a écrit :
>
> 2014-11-17 9:40 GMT+01:00 Matt Calabrese <rivorus_at_[hidden]>:
>>
>> On Sun, Nov 16, 2014 at 11:04 PM, Andrzej Krzemienski <
>>> akrzemi1_at_[hidden]>
>>> wrote:
>>>
>>> Hi Everyone,
>>>> I would like to run an idea through everyone in this list. There is a
>>>> recurring complaint about Boost.Optional that it allows you to do
>>>>
>>> "unsafe"
>>>
>>>> things:
>>>> 1. Inadvertent mixed comparisons between T and optional<T>
>>>> 2. Unintended conversion from T to optional<T>
>>>> 3. "Unchecked" access to the contained object, which causes an UB when
>>>> performed on an uninitialized optional object.
>>>>
>>>> There are valid reasons why optional is defined the way it is defined.
>>>>
>>> But
>>>
>>>> at the same time the complaints above are also valid. This makes some
>>>> people abandon Boost.Optional and use their own alternative.
>>>>
>>>> I don't immediately see the problem with the mixed comparisons between
>>> T
>>> and optional T... except maybe confusion regarding optional<bool> or
>>> bool-like types. Is this what you're referring to? If so, then I sort of
>>> disagree that it's a legitimate problem. If you are not talking about
>>> issues relating to bool or have some really compelling optional<bool>
>>> cases, can you point me to examples as to why this is suggested to be
>>> unsafe. I don't really care that much about the mixed comparisons, but I
>>> consider them pretty benign and if people find it useful then I won't
>>> remove it unless the current uses are fully considered.
>>>
>>> As for #2, I think I agree that conversion should probably be more
>>> explicit
>>> and is potentially a step in a positive direction.
>>>
>>> As for #3, if you are implying the alternative is to throw an exception,
>>> then I'd say that's a flat-out no. That's a logic error and we shouldn't
>>> throw an exception. The only thing that comes of that is people using the
>>> exception for basic control flow -- if they knew the optional didn't
>>> point
>>> to anything, then they wouldn't be dereferencing it. If they THOUGHT the
>>> optional pointed to something and it didn't, then they have a bug, which
>>> means the way to "handle" it is to fix the code. If they don't know at
>>> the
>>> time of the access whether there was something there or not, then they
>>> shouldn't deference it, using an exception for control flow. In that last
>>> case, they should either be explicitly branching or they should use some
>>> kind of visitation. If you're not talking about exceptions, then what
>>> exactly are you proposing?
>>>
>>> No, no exceptions.
>> The solution is based on the observation that there is a limited number of
>> things you can do with optional<T>
>>
>> optional<int> oi = ...;
>>
>> 1:
>> if (oi) doSomething(*oi);
>> else doSomethingElse(); // or nothing
>>
>> 2:
>> if (oi) doSomething(*oi);
>> else doSomething(-1); // use default value
>>
>> 3:
>> if (!oi) oi = (int)getIntByOtherMeans();
>> doSomething(*oi); // now it is safe
>>
>> Now we simply provide a dedicated interface for each of these three
>> usages:
>>
>> 1:
>> oi.use(&doSomething, &doSomethingElse); // or use lambdas
>>
> This is the idea of visitation and try-catch behind this function. What
> would be the result of this use function? Should both functions return the
> same type?
>
> I would suggest to call this accept or match. In addition this could be a
> free function
>
> auto x = match(oi,
> [] (int i) {},
> [] () {}
> );
> The function could take several optional
>
> auto x = match(make_tuple(oi, os),
> [] (int i, string const& s) {},
> [] (...) {}
> );
>
>
>> 2:
>> doSomething(oi.value_or(-1));
>>
> I believed this was already part of the interface.
>
>
>
>> 3:
>> doSomething(oi.value_or_eval(getIntByOtherMeans));
>>
>>
>>

> Why do we need a new safe_optional class to add these features?
>

Because once we have the three above (2 and 3 already present in
boost::optional) we can remove all other interface that has a potential to
cause confusion or UB.

>
> Best,
> Vicente
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/
> mailman/listinfo.cgi/boost
>


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