Boost logo

Boost :

Subject: Re: [boost] compact_optional -- prompting interest
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2015-09-26 17:34:59


On Sat, Sep 26, 2015 at 7:52 PM, Andrzej Krzemienski <akrzemi1_at_[hidden]> wrote:
> 2015-09-25 17:37 GMT+02:00 Andrey Semashev <andrey.semashev_at_[hidden]>:
>>
>> However, I'm not sure I agree with your rationale on the reduced interface
>> and possibly the compact_optional naming.
>>
>> 1. You chose not to provide relational operators for compact_optional
>> because you don't know how to order 'empty' values. I think you don't have
>> to make that decision and simply forward the call to the underlying type. I
>> mean, you always have the stored object constructed in some state and as
>> long as it implements operators you can always use them.
>
> So this is a trade-off between convenience/expressiveness and the potential
> to detect unintended semantics at compile-time. If there is sufficient
> argumentation in favor of adding them, I can always do it. As Rob says,
> this can also be encoded in the policy.

It can, but I really don't see the reason for it. Can you give an
example where operators defined for type T are not sensible to
compact_optional<policy<T> >?

>> 2. compact_optional does not provide direct assignment of the values of
>> the stored type, requiring to manually construct a compact_optional-wrapped
>> value. To me, this is too cumbersome to use while I don't see any wins from
>> this restriction. Besides more typing, this essentially requires to use a
>> typedef to declare and use the compact_optional variable.
>
> Are you proposing a member function like opt.store_raw_value(v); ?

No, I was suggesting to allow assignment of values of type T (i.e.
"opt = v;"). Having a named function like store_raw_value reduces the
need in the typedef but the syntax should still be simpler.

You may object that this allows the assignment to make the opt object
empty (or null, or singular - not sure what terminology you prefer).
This may seem counterintuitive at first glance, but only as long as
you treat the type as another flavor of optional<>, which is incorrect
and is one reason why the name should be changed. What
compact_optional really is is just a wrapper that allows to easily
distinguish a special value of the governed object from all other
values, and in that light there's nothing wrong if assigning this
special value to the wrapper makes it singular. Analogously, there's
nothing wrong with assigning a nullptr to a pointer.

> I am not particularly tied to name compact_optional. I can be persuaded to
> rename it. On the other hand, I am not in favor of any names containing
> "null". I am not an English speaker, but no me "null" sounds like "numeric
> value zero", which makes sense for the pointer, but not for something that
> just is not. Maybe "singular" or "special".

Well, I'm not a native speaker but AFAIK null does literally mean zero
in English. However, in the programming domain I don't see null as
something that is necessarily equivalent to a zero value. It's more
like a 'special value' to me. E.g. in databases null is a special
value that has no connection to zero at all. Even in C++ null pointers
are not required to have zero value as the underlying implementation.

But I'm not insisting on nullable<>. There's also a close alternative
of nilable<>. Singular is the characteristic of a particular value,
not the type or range of values, so it's difficult to compose a name
from it (I believe, 'singularable' is not a word). Special is too
generic, IMHO. We can go a different way: nav_adapter<> (where nav
stands for not-a-value) or singular_adapter<>. Although I like it less
than nullable.

>> 5. A suggestion: add evp_zero and evp_empty policies. The first uses
>> literal zero as the special value and can be used with numeric (integer and
>> fp) and pointer types. The second uses a default constructed value as the
>> magic value and a member empty() function to test for magic value. This
>> could be useful with containers, strings and ranges.
>
> Agreed on evp_empty, but I fail to see the advantage of evp_zero over the
> already existing evp_value_init. The later uses the value initialized T,
> which already is zero for ints, floats and pointers. Or do you expect the
> comparison to literal 0 to be faster?

Oh, it didn't occur to me until your reply that evp_value_init already
covers the evp_zero use cases. Ok, good, no need for evp_zero.


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