|
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);
or
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);
else
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("___") ];
else
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.
Best,
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk