|
Boost : |
Subject: Re: [boost] [optional] Safe optional
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2014-11-20 17:13:42
2014-11-20 21:57 GMT+01:00 Vladimir Batov <Vladimir.Batov_at_[hidden]>
:
>
> On 11/20/2014 08:29 PM, Andrzej Krzemienski wrote:
>
>> 2014-11-19 22:36 GMT+01:00 Vladimir Batov <Vladimir.Batov_at_constrainttec.
>> com>
>>
>> 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.
>>
>
> 1. I am not (and never have been) advocating that "optional" is a
> container. I personally find it wrong... maybe interesting for curiosity
> sake but ultimately misleading and distracting.
>
> 2. I do understand and do agree with the decision made regarding
> "optional" sorting -- no-value is less than "any" value. Seems sensible and
> easily "documentable" and makes "optional" easily usable in ass. containers
> without hassle.
>
> 3. What I have doubts about (and I stress -- doubts -- as indicated by my
> previous conflicting posts) is op<(T, optional<T>). Yes, *mechanically*,
> one can say -- T is implicitly propagated to optional<T> and then
> op<(optional<T>, optional<T>) is applied. Easy-peasy. I wish life was that
> straightforward.
>
> *It feels to me* that, when T is compared to optional<T>, it is quite
> likely a bug -- it's far too open for misuse and (mis)interpretation. Based
> on that feeling I tend to suggest banning op<(T, optional<T>). With that we
> "kill two birds" -- (a) we address the safety concern you raised and (b) we
> achieve that within the "optional" framework without losing any existing
> functionality.
>
> 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.
>>
>
> Here with all due respect I have to cautiously disagree... probably due to
> too broad a brush you are using to paint the picture. I have no issue with
> T to optional<T> implicit conversion. I think it's essential. What I am
> cautious about is when and how liberally that conversion is applied.
> "Always" just does not sit well with me. The idea that you are seemingly
> advocating seems unduly mechanical -- when we need to do anything with a T
> and optional<T> pair, then propagate T to optional<T> and then apply the
> "optional natural model". The problem (as I see it) is that, when we are in
> the T land, we apply T rules, when we are in the optional<T> land, we apply
> optional<T> rules. However, when we have T *and* optional<T>, we are right
> on the border. You say, "apply optional<T> rules". I say "I do not know"
> and, therefore, as a library writer I want to leave that decision to the
> user -- i.e. force him to be explicit, i.e. "t < *ot" or "optional<T>(t) <
> ot". Does it make sense?
>
It does. You are also correct to observe that we have started talking more
about feelings than anything that can be objectively asserted. I am forced
to admit I might be tempted to apply a too simplistic view. But that is
still too little for me to get convinced that we should allow the
converting constructor and poison the mixed operator less at the same time.
I agree that there is no solution here that would be considered
satisfactory by everyone, so we are forced to select the least of two
evils, and it seams that there is no objective way of even measuring the
two evils.
The usage of converting constructor in optional only shows to me that we
have not established a good criteria for telling when having a converting
constructor is a good idea. I always used to think that if only you are not
loosing any information, it is safe. But in the case of optional I can see
that even then it can have some negative consequences. Perhaps it is the
way the language is designed that is wrong: that you either allow this
conversion in every possible situation or never at all.
>
> Yet, many people make this invalid expectation,
>>
>
> Hmm, maybe those expectations are not as invalid as you are trying to
> present them. I am hoping the paragraph above clarifies my feeling about it.
>
Ok, that was too blunt. For one, I admit I fell into this trap myself at
least once. But then I am trying to remain sane.
In the end, I acknowledge the concern about potential pitfalls. Still, I
find a value in that I am able to tell what optional IS and then reason
from that what operations it will have and with what semantics. With
poisoned mixed comparison optional would be a set of safety patches that do
not amount to a coherent meaning. It would be safer, but it would be a
headache, because you would never know what it is.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk