Boost logo

Boost :

From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2008-06-02 11:45:02


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sunday 01 June 2008 20:41 pm, Hartmut Kaiser wrote:
> > > What's the difference between treating a future as a placeholder and
> > > having a future implicitly convertibly to its result type? Doesn't a
> > > placeholder imply having this implicit conversion?
> >
> > Yes, that's why I added it. I just think it's a little dangerous (see
> > following paragraph). For example, boost::optional is a stand-in for
> > its templated type, but it only supports implicit conversion from T to
> > optional<T>, and not from optional<T> to T. Maybe a future_value
> > should do the same.
>
> That's exactly my point! For this reason I don't think having the default
> implicit conversion operator for futures is a good idea. But I'm starting
> to repeat myself. I so won't comment any further on this thread.

I think we're having some misunderstanding due to when you say "future", I
hear "future_value", instead of what you mean when you say "future". I'll
call that "future_handle" here for clairity.

> That's better than the initial proposal but still much more complicated
> than it could be: (f1 || f2) && f3. Just think about more complex logical
> execution constraints, these won't be readable anymore when using the
> function based syntax. Why do you object against using such a simple
> syntax, even if it's now obvious that it has additional advantages over
> your function based proposal (coherent return value treatment)?
>
> But again: I'm repeating myself, so there won't be any further comments
> from my side. If the authors of the future Boost futures library object
> against providing the logical operators it will be easy enough for me to
> implement those solely on top of the library... This is no reason for me to
> vote against it.

Yes, I've attached an example of how a user could implement your operator&&
and operator|| in terms of future_select and future_combining_barrier. Of
course, they could also choose to implement a lot of other things too
(including operators with slightly different semantics) with
future_combining_barrier.

> But I will vote against a library implementing implicit conversion to the
> result type of the future: future<T> to T.

I'd like to try and summarize and comment a bit on what we've discussed. We
have two ideas that have both been referred to as a future:

1) future_handle: A minimal, focused class. This is essentially William's
proposal. One feature I do believe belongs in future_handle is conversion
from any future_handle<T> to future_handle<void>. William's proposal does
not support this, but Gaskill's does.

2) future_value: A slightly more complex and featureful class, whose objects
can be used as a stand-ins for objects of its template type. This is useful
for things like lifting ordinary functions into asyncronous ones that use
future_value for their return values and input parameters. future_value
might _not_ want to support conversion of arbitrary future_value<T> to
future_value<void>. Otherwise, it is a future_handle that adds support for:

2a) construction/assignment of future<T> from future<U>, if it is supported by
T and U. I believe this is supported by Gaskill's.

2b) construction/assignment of future<T> from T, and maybe (or maybe not) the
opposite direction: implicit conversion from future<T> to T. Gaskill's only
supports the (more dangerous) conversion from T to future<T>.

My use case requires future_value. Furthermore, from my experience
implementing the future_value features in poet::future, I doubt it will be
possible to implement future_value relying only the public interface of
future_handle. Thus, a class like future_value would have to be part of the
futures library so it can access and extend the future_handle internals. If
the futures library doesn't provide a future_value, it will be of no use to
me since I'll have to continue providing my own independent futures
implementation.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRBWF5vihyNWuA4URAgKMAJ4ulvjuJaS6/ko6NESm3dJ+gylFhACgsoxM
lMQN/TnaQ//w79roS+kKrxw=
=R8Xk
-----END PGP SIGNATURE-----

--Boundary-00=_FWBRIf35oXLuiHi
Content-Type: text/x-c++src; charset="iso-8859-1"; name="future_operators.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
        filename="future_operators.cpp"

#include <boost/tuple/tuple.hpp>
#include <boost/variant/variant.hpp>
#include <poet/future_barrier.hpp>
#include <poet/future_select.hpp>

template<typename T1, typename T2>
boost::tuple<T1, T2> create_tuple(const T1 &a1, const T2 &a2)
{
        return boost::tuple<T1, T2>(a1, a2);
}

template<typename T1, typename T2>
poet::future<boost::tuple<T1, T2> > operator&&(const poet::future<T1> &f1, const poet::future<T2> &f2)
{
        return poet::future_combining_barrier<boost::tuple<T1, T2> >(&create_tuple<T1, T2>, f1, f2);
}

template<typename R, typename T>
R convert(const T &t)
{
        return t;
}

template<typename T1, typename T2>
poet::future<boost::variant<T1, T2> > operator||(const poet::future<T1> &f1, const poet::future<T2> &f2)
{
        typedef boost::variant<T1, T2> result_type;
        poet::future<result_type> variant_f1 = poet::future_combining_barrier<result_type>(&convert<result_type, T1>, f1);
        poet::future<result_type> variant_f2 = poet::future_combining_barrier<result_type>(&convert<result_type, T2>, f2);
        return poet::future_select(variant_f1, variant_f2);
}

--Boundary-00=_FWBRIf35oXLuiHi--


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