Boost logo

Boost :

Subject: Re: [boost] [optional] operator<(optional<T>, T) -- is it wrong?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2014-11-26 02:12:56

Le 26/11/14 06:26, Vladimir Batov a écrit :
> Vicente Botet wrote
>> ...
>> Following your reasoning, I will suggest to remove the implicit
>> construction from T to optional
>> <T>
>> and/or remove the
>> operator<(optional
>> <T>
>> , optional<>). If we can not live without them, we
>> could always try to do whatever is better.
> Vicente, you are not serious, right?.. It is just that you did not
> like/agree with my "reasoning" and, so you suggested something unreasonable
> (IMO) and presented it as a "consequence" of my "reasoning" just to indicate
> how ridiculous mine was... Was that the idea?... Or I am misunderstanding
> you post?
Vladimir, yes and not. Were talking of the possibility of a new
safe_optional. I would like we explore how we would like to have this
new type.
> I cannot live without implicit T to optional<T> and prohibiting it will
> break tonnes of my code and project code and Fernando Cacciola's code (if I
> remember our similar discussions years ago)... and it'll break all that code
> *now*... no need to wait and see... and "selling" optional<T> without
> implicit T to optional<T> will be real hard... in my neck of the woods
> anyway.
I understand your backward compatibility concern? I'm not suggesting at
all to change boost::optional.
I'm looking on how all these conversions can be made safer.

You surely remember my Boost.Conversion proposal that was rejected. I
believe that there is something interesting behind this idea.
The idea is to state explicitly that you want a explicit conversion but
don't state to what. The what is deduced from the context.
Boost.Conversion was a library proposal. We could rethink it as a
language proposal. Let me represent by

[ x ]

this explicit conversion to the context.
With this we could be able to

   optional<int> f(int x) {
     if (x<0)
         return nullopt ;
     return [ x ];

[ x ] is longer than x but shorter than make_optional(x).

The meaning of

    return [ x ]

on the context of a function returning M would be given by

   return M(x);

We could also add an indirection and translate it to

   return make_explicitly(type<M>{}, x);


   return type<M>{}[x];

where the type<M> instance is used only to be able to overload on M.

    template <class T>
    struct type {};

The default implementation could then be a call to the explicit
constructor of the context from the parameter

   // default to explicit constructor
   template <class M, class X>
   M make_explicitly(type<M>, X && x) { return M(std::forward<T>(x)); }

We could stop here or we could use [ x ] not only on a return statement
but also in any expression as in

    optional<int> oi;
    int x;
    if ( oi < [x] )

Note that we don't need an implicit conversion from T to optional<T>
then but only an explicit one, avoiding the more verbose

   if ( oi < std::make_optional(x) )

This can be applied also on the context of the await proposal to
separate the concerns. await will take care of the the continuation part
and {{}} will take care explicit conversion transformation.

future<int> f(int x) {
   if (x > 10)
     return await something_long(x);
     return [ x + 1 ]; // make_ready_future

This operator could be used also to mean the empty set, as in

set<int> f {

   return [];

Another example

variant< int, string> f(int x) {
   if (x > 10)
     return [ std::string("___") ];
     return [ x + 1 ];

Indirectly Herb Sutter proposal [n4074] "Let return {expr} Be Explicit"
and Gor Nishanov [4134] Resumable functions proposal interact with this
implicit explicit conversion thing.

I don't know how to implement in C++14 the mreturn Haskell

Monad m =>mreturn :: a -> m a

as C++14 doesn't consider the context of the call and so the m can not
be deduced.

I hope it is clear now that I don't want to change optional but see what
the safer optional could be with the ongoing C++ proposals.


Boost list run by bdawes at, gregod at, cpdaniel at, john at