Updated version of futures library

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Re: Updated version of futures library

by Frank Mori Hess-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 31 May 2008 21:19, Hartmut Kaiser wrote:

> I'm perfectly aware of this. And actually I expressed exactly the same
> by pointing out the main difference between the two sets of operators:
> the logical operators I proposed are for the futures themselves while
> the others are related to the future results.
>
> But you're diligently ignoring my point: overloading the operators for
> the future results is conceptually equivalent to having a default
> conversion operator to the result type for the future itself! And for
> that reason I would not like to see something like that in the future
> library.
Ah, I think I'm understanding you better now.  You are appalled by the idea
of treating a future<T> like it was a T, is that correct?  You want a
future<T> to only be treated like an abstract handle to a value, not the
value itself?  I wasn't ignoring your point, it's just that your view is
extremely foreign to how I view futures, so your words were almost
meaningless to me.  I view being able to view a future<T> as a placeholder
for a T object as a large part of what makes futures useful.  I
implemented the future class in libpoet to support that, with implicit
conversions from future<T> to future<U>, from T to future<T>, etc.  And
being able to treat a future<T> as a placeholder for a T is essential to
implementing things like poet::active_function.  

I don't particularly like the implicit conversion from T to future<T>, but
that has absolutely nothing to do with not wanting to treat a future<T> as
a placeholder.  It's simply because the conversion can block, and thus
produce unexpected behavior (an object appearing on the right hand side of
an assignment stalling your program).  The explicit future::get() at least
gives a hint that something more than a quick conversion might be
happening.

I guess the features that allow a future to act as a placeholder could be
split out into a separate higher level class, call it "future_value",
which would internally contain a plain old future.  The idea doesn't
really do anything for me, but maybe you would find it preferable?

> OTOH, IMHO, having the logical operators alone improves code
> readability, simplifies the implementation (by avoiding multiple
> overloads for different parameter counts), allows to build more complex
> logical execution restrictions as (f1 || f2) && f3 (which is not
> possible using the proposed wait_for_all and wait_for_any), and all that
> without having to sacrifice any of the existing functionality.

The
poet::future_barrier/future_composing_barrier/future_select/future_selector
stuff I'm currently working on allows for composition.  Did you see the
earlier discussion on this a couple weeks ago?  For example this thread:

http://lists.boost.org/Archives/boost/2008/05/137417.php

>
> > Personally, I don't particularly want to see a future
> > library overload any logical operators at all, or at least have the
> > overloads sequestered in separate headers that aren't included by any
> > of the other future library headers.
>
> That's a matter of taste, for sure. But would you mind telling us why
> you don't want to have these? Your opinion sounds to be quite strong, so
> you must have good reasons!

It's the obvious reason.  I don't think taking a function with a 2 letter
name, which is already overloaded, and adding a new set of overloads to it
which have semantics completely unrelated to the existing overloads is a
desirable or aesthetically pleasing interface.  No one would even consider
doing such a thing if the function wasn't an operator.  I guess I just
don't find operator syntax as compelling a feature as others.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

attachment0 (196 bytes) Download Attachment

Re: Updated version of futures library

by Frank Mori Hess-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 31 May 2008 23:21, Frank Mori Hess wrote:
> I don't particularly like the implicit conversion from T to future<T>,

Err, I meant future<T> to T.

> but that has absolutely nothing to do with not wanting to treat a
> future<T> as a placeholder.  It's simply because the conversion can
> block, and thus produce unexpected behavior (an object appearing on the
> right hand side of an assignment stalling your program).  The explicit
> future::get() at least gives a hint that something more than a quick
> conversion might be happening.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

attachment0 (196 bytes) Download Attachment

Re: Updated version of futures library

by Felipe Magno de Almeida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Jun 1, 2008 at 12:21 AM, Frank Mori Hess <fmhess@...> wrote:
> On Saturday 31 May 2008 21:19, Hartmut Kaiser wrote:

[snip]

>> > Personally, I don't particularly want to see a future
>> > library overload any logical operators at all, or at least have the
>> > overloads sequestered in separate headers that aren't included by any
>> > of the other future library headers.
>>
>> That's a matter of taste, for sure. But would you mind telling us why
>> you don't want to have these? Your opinion sounds to be quite strong, so
>> you must have good reasons!
>
> It's the obvious reason.  I don't think taking a function with a 2 letter
> name, which is already overloaded, and adding a new set of overloads to it
> which have semantics completely unrelated to the existing overloads is a
> desirable or aesthetically pleasing interface.  No one would even consider
> doing such a thing if the function wasn't an operator.  I guess I just
> don't find operator syntax as compelling a feature as others.

I tend to agree with Frank's view of overloading && and || for futures.
I'm surely not a never-overload-operators-guy. I, for instance, love spirit.
But in spirit && and || has a specific meaning inside EBNF domain.
In futures, we're just inventing that meaning.
Couldn't lambda's help us more than overloading here?

--
Felipe Magno de Almeida
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sunday 01 June 2008 06:34, Felipe Magno de Almeida wrote:

> >> That's a matter of taste, for sure. But would you mind telling us why
> >> you don't want to have these? Your opinion sounds to be quite strong,
> >> so you must have good reasons!
> >
> > It's the obvious reason.  I don't think taking a function with a 2
> > letter name, which is already overloaded, and adding a new set of
> > overloads to it which have semantics completely unrelated to the
> > existing overloads is a desirable or aesthetically pleasing interface.
> >  No one would even consider doing such a thing if the function wasn't
> > an operator.  I guess I just don't find operator syntax as compelling
> > a feature as others.
>
> I tend to agree with Frank's view of overloading && and || for futures.
> I'm surely not a never-overload-operators-guy. I, for instance, love
> spirit. But in spirit && and || has a specific meaning inside EBNF
> domain. In futures, we're just inventing that meaning.
> Couldn't lambda's help us more than overloading here?
Oh, I came up with another reason.  A future can be empty (default
constructed, or a moved unique_future).  Such classes often support
converson to bool (or conversion to "unspecified boolean type" when they
want to be safer) to test if they have been initialized.  So seeing a
future in a logical operator, one might mistakenly assume the operator is
is a test to see if either or both futures have been initialized.

Although, to nit-pick myself, I don't think the statement I made about the
logical operators already being overloaded was technically correct.  I
suppose its really the conversion-to-bool operator that is overloaded and
there is just the bool prototype for the logical operators.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

attachment0 (196 bytes) Download Attachment

Re: Updated version of futures library

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank,

> > I'm perfectly aware of this. And actually I expressed exactly the
> same
> > by pointing out the main difference between the two sets of
> operators:
> > the logical operators I proposed are for the futures themselves while
> > the others are related to the future results.
> >
> > But you're diligently ignoring my point: overloading the operators
> for
> > the future results is conceptually equivalent to having a default
> > conversion operator to the result type for the future itself! And for
> > that reason I would not like to see something like that in the future
> > library.
>
> Ah, I think I'm understanding you better now.  You are appalled by the
> idea of treating a future<T> like it was a T, is that correct?  

Yep. That's the separation of concerns I was alluding to. Futures should do
one thing, and that is encapsulating deferred or eager execution of a
(remote) task.

> You
> want a future<T> to only be treated like an abstract handle to a value,
> not the value itself?  I wasn't ignoring your point, it's just that
> your view is extremely foreign to how I view futures, so your words
> were almost meaningless to me.  I view being able to view a future<T>
> as a placeholder for a T object as a large part of what makes futures
> useful.  I implemented the future class in libpoet to support that,
> with implicit conversions from future<T> to future<U>, from T to
> future<T>, etc.  And being able to treat a future<T> as a placeholder
> for a T is essential to implementing things like poet::active_function.
>
> I don't particularly like the implicit conversion from T to future<T>,
> but that has absolutely nothing to do with not wanting to treat a
> future<T> as a placeholder.  

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?

> It's simply because the conversion can
> block, and thus produce unexpected behavior (an object appearing on the
> right hand side of an assignment stalling your program).  The explicit
> future::get() at least gives a hint that something more than a quick
> conversion might be happening.
>
> I guess the features that allow a future to act as a placeholder could
> be split out into a separate higher level class, call it
> "future_value", which would internally contain a plain old future.  The
> idea doesn't really do anything for me, but maybe you would find it
> preferable?

I could live with that. The future_value would be implemented on top of
anything encapsulating deferred/eager remote execution and its sole purpose
is to provide implicit conversion, function argument lifting, etc. No mixing
of concerns here, fine.

> > OTOH, IMHO, having the logical operators alone improves code
> > readability, simplifies the implementation (by avoiding multiple
> > overloads for different parameter counts), allows to build more
> > complex logical execution restrictions as (f1 || f2) && f3 (which is
> > not possible using the proposed wait_for_all and wait_for_any), and
> > all that without having to sacrifice any of the existing
> functionality.
>
> The
> poet::future_barrier/future_composing_barrier/future_select/future_sele
> ctor
> stuff I'm currently working on allows for composition.  Did you see the
> earlier discussion on this a couple weeks ago?  For example this
> thread:
>
> http://lists.boost.org/Archives/boost/2008/05/137417.php

I didn't follow this discussion, thanks for the link.

> > > Personally, I don't particularly want to see a future library
> > > overload any logical operators at all, or at least have the
> > > overloads sequestered in separate headers that aren't included by
> > > any of the other future library headers.
> >
> > That's a matter of taste, for sure. But would you mind telling us why
> > you don't want to have these? Your opinion sounds to be quite strong,
> > so you must have good reasons!
>
> It's the obvious reason.  I don't think taking a function with a 2
> letter name, which is already overloaded, and adding a new set of
> overloads to it which have semantics completely unrelated to the
> existing overloads is a desirable or aesthetically pleasing interface.
> No one would even consider doing such a thing if the function wasn't an
> operator.  I guess I just don't find operator syntax as compelling a
> feature as others.

Come on. You and I _know_, that an operator isn't just a function with a two
letter name (and as you admitted in a later mail, they aren't yet
overloaded, so your reasoning isn't really convincing). An operator is
certainly more than that, i.e. it provides infix notation, well defined
associativity and precedence rules, terse expression syntax, etc.

The semantics might be unusual, I agree. But the same was true when Bjarne
introduced the shift operators for input/output. Nowadays nobody even
discusses this anymore, it's just 'natural'. Once you think about it for a
while it's very 'natural' as well to use || and && to express logical
execution restrictions for futures - not their values, giving you a very
powerful means of controlling fine grained parallelization.

BTW, we could go even further by overloading '->', '>>', or '>>=' to express
dependencies between futures (except that >>= probably has the wrong
precedence for that, just a hunch, I didn't check). This would be just
another means of controlling parallelization while using an easy
understandable syntax. But I'm not going to propose _that_ :-P

And just compare the amount of code needed to write something equivalent to
(f1 || f2) && f3 using the proposed API from the link you gave me above.
That's really appalling - certainly only IMHO!

Regards Hartmut



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sunday 01 June 2008 14:43, 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.

> > It's simply because the conversion can
> > block, and thus produce unexpected behavior (an object appearing on
> > the right hand side of an assignment stalling your program).  The
> > explicit future::get() at least gives a hint that something more than
> > a quick conversion might be happening.

>
> And just compare the amount of code needed to write something equivalent
> to (f1 || f2) && f3 using the proposed API from the link you gave me
> above. That's really appalling - certainly only IMHO!
>

I guess you're talking about Johan's initial proposal?  In my current code,
that is roughly

future_select(future_barrier(f1, f2), f3)

although that particular expression would produce a future<void> instead of
a

future<tuple<variant<T1, T2>, T3>

If the user wanted composing functions or operators that returned
tuples/variants, they could implement them without much trouble using
future_combining_barrier.  Unfortunately, I don't have any documentation
or the latest version of my code online yet, but hopefully next week.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

attachment0 (196 bytes) Download Attachment

Re: Updated version of futures library

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> > 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.

> > > It's simply because the conversion can block, and thus produce
> > > unexpected behavior (an object appearing on the right hand side of
> > > an assignment stalling your program).  The explicit future::get()
> at
> > > least gives a hint that something more than a quick conversion
> might
> > > be happening.
>
> > And just compare the amount of code needed to write something
> > equivalent to (f1 || f2) && f3 using the proposed API from the link
> > you gave me above. That's really appalling - certainly only IMHO!
>
> I guess you're talking about Johan's initial proposal?  In my current
> code, that is roughly
>
> future_select(future_barrier(f1, f2), f3)
>
> although that particular expression would produce a future<void>
> instead of a
>
> future<tuple<variant<T1, T2>, T3>
>
> If the user wanted composing functions or operators that returned
> tuples/variants, they could implement them without much trouble using
> future_combining_barrier.  Unfortunately, I don't have any
> documentation or the latest version of my code online yet, but
> hopefully next week.

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.

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

Thanks for the insightful discussion.
Regards Hartmut


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

-----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-----

[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);
}


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 11:45 am, Frank Mori Hess wrote:
> 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>.

Err, I seem to keep getting that backwards.  I meant Gaskill's only supports  
future<T> to T.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRBeS5vihyNWuA4URAjJ/AKCOkGYNYsiptj+Vwcx++6cT+NHj+QCdG2It
uPMQ1QfDvuxsKxptZqzrID4=
=zD2U
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Peter Dimov-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess:

> My use case requires future_value.

I generally try to follow the future-related discussions, but do not recall
seeing an explanation of the specifics of your use case. Can you please
point me to one?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 11:55 am, Peter Dimov wrote:
> Frank Mori Hess:
> > My use case requires future_value.
>
> I generally try to follow the future-related discussions, but do not recall
> seeing an explanation of the specifics of your use case. Can you please
> point me to one?

Oh, my use case is the "lifting of an ordinary function to an asynchronous one
that takes/returns future_value objects" I mentioned earlier in the post.  To
be more specific:

http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/active_function.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRBq75vihyNWuA4URAtR0AKC4eAtIq+P1bKiPcEL0r9xGUNwRFACgyDOg
3qjarkoZVbq9cVkjy0Ix15k=
=aeip
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 11:45 am, Frank Mori Hess wrote:
> 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.  

Actually, let me back down from that a little.  I think if the futures library
provided a future_combining_barrier (which I was grouping with the
future_value functionality in my head before), I could implement a
future_value on top of a future_handle.  

To elaborate, the future_combining_barrier would let you produce a
future_handle<R> from a heterogeneous group of input future_handle objects,
plus a user-supplied combiner function.  The combiner is called to produce
the value for the future_handle<R> from the values of the input
future_handles when they are ready.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRCEY5vihyNWuA4URAnTGAKCVERqhgxyCistma9Tl9en01h3SYgCgkgX4
1gqqfSTzFnUK8/l6XFy8Dik=
=UZG0
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Johan Torp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess wrote:
> > My use case requires future_value.
>
> I generally try to follow the future-related discussions, but do not recall
> seeing an explanation of the specifics of your use case. Can you please
> point me to one?

Oh, my use case is the "lifting of an ordinary function to an asynchronous one
that takes/returns future_value objects" I mentioned earlier in the post.  To
be more specific:

http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/active_function.html
To clarify some of my posts and another use case; I have been thinking a lot about a lazy "passive function" which is rather analogous to an active function. The difference is that evaluation work is not done by an associated thread, but by a future-listening thread in it's wait, get or is_ready calls.

In general any function:
  R foo(A1 a1, A2 a2)
can be "lifted" to a passive or active function if any of it's arguments needs to be supplied asynchronously. This can be done either totally;
  future<R> foo(future<A1> a1, future<A2> a2)
or partially;
  future<R> foo(future<A1> a1, A2 a2)

I hope that futures will be enough computationally powerful to implement "passive lifting" and that it won't be too cumbersome for users to express this.

Johan

Re: Updated version of futures library

by Peter Dimov-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess:
> Oh, my use case is the "lifting of an ordinary function to an asynchronous
> one
> that takes/returns future_value objects" I mentioned earlier in the post.
> To
> be more specific:
>
> http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/active_function.html

Hm.

It would be nice if you could provide a better motivating example. :-)

That aside, I'm not sure why you need future_value semantics. Let's assume
that one has a primitive

    future<R> async( F f, A1 a1, ..., An an );

that schedules bind(f,a1,a2,...,an) for execution. It wouldn't be hard to
make it recognize when Ai is future<Bi> and do the following instead:

async_with_guard(

    bind( A1::ready, a1 ) && ...,

    f,

    bind( A1::get, a1 ), ... );

The 'guard' predicate is just symbolic since the scheduler would in reality
store the futures as dependencies and use the appropriate "multi-multiwait".
But the point is that I don't see the above requiring any
future_value-specific operations.

Or stated differently:

future<double> fd1 = async( f1, 0 );
future<double> fd2 = async( f1, 1 );

future<double> fd = async( f2, fd1, 0.3, fd2, 0.7 );

// actually does:

future<double> fd = async_with_dependencies(

    bind( f2,
        bind( future<double>::get, fd1 ), 0.3,
        bind( future<double>::get, fd2 ), 0.7 ), // function object

    fd1, fd2 ); // dependency list

In this case one would need to use something like protect(fd1) if the
function really takes a future.

It's not clear whether the goal of libpoet is to provide fine-grained
parallelism or lazy evaluation; if the latter, one could expect all
functions to take futures, since an active_function provides no fine-grained
laziness. In this case the above "activize by default" approach won't be
very convenient.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 13:02 pm, Peter Dimov wrote:

> Frank Mori Hess:
> > Oh, my use case is the "lifting of an ordinary function to an
> > asynchronous one
> > that takes/returns future_value objects" I mentioned earlier in the post.
> > To
> > be more specific:
> >
> > http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/
> >active_function.html
>
> Hm.
>
> It would be nice if you could provide a better motivating example. :-)

Well, I want the "lifted" versions of functions to be as useable as ordinary
functions.  So, you can compose functions whose types don't match exactly:

float f();
void g(double x);
g(f()); //fine

But not the version lifted to future_handles:

future_handle<float> lifted_f();
future_handle<void> lifted_g(future_handle<double> x);
lifted_g(lifted_f()); // error, no implicit conversions for future_handle

> That aside, I'm not sure why you need future_value semantics. Let's assume
> that one has a primitive
>
>     future<R> async( F f, A1 a1, ..., An an );
>
> that schedules bind(f,a1,a2,...,an) for execution. It wouldn't be hard to
> make it recognize when Ai is future<Bi> and do the following instead:
>
> async_with_guard(
>
>     bind( A1::ready, a1 ) && ...,
>
>     f,
>
>     bind( A1::get, a1 ), ... );
>
> The 'guard' predicate is just symbolic since the scheduler would in reality
> store the futures as dependencies and use the appropriate
> "multi-multiwait". But the point is that I don't see the above requiring
> any
> future_value-specific operations.

That's interesting.  The binds you describe in async_with_guard play a role
similar to my future_combining_barrier(), except they need a scheduler thread
to evaluate them, whereas the user functor passed to future_combining_barrier
will be evaluated by whatever thread tries to use the returned future once
its future dependencies are all ready.  And as I realized and posted a couple
hours ago, future_combining_barrier plus a future_handle would be sufficient
for me to implement a future_value on top of.

However, the William's future does not currently support any multi-multiwait.  
Its wait_for_all and wait_for_any do not return futures but block when
called.  The Gaskill futures do have operator|| and operator&& but they are
not efficient enough to build a scheduler on.  So, I'd like to see something
like the future_select, future_barrier, future_selector,
future_combining_barrier stuff I'm working on in libpoet in the boost futures
library.  None of them require a future_value.

> It's not clear whether the goal of libpoet is to provide fine-grained
> parallelism or lazy evaluation;

active_function provides fine-grained parallelism.  Or, maybe
adjustable-grained, since multiple active_functions can share the same
scheduler thread.  Lazy evaluation can be achieved with
future_combining_barrier (which isn't in the online docs or any release yet).

> if the latter, one could expect all
> functions to take futures, since an active_function provides no
> fine-grained laziness. In this case the above "activize by default"
> approach won't be very convenient.

You can get fine-grained laziness by using future_select in conjunction with
future_combining_barrier.  For instance, if you wait on a future returned by
future_select, and the inputs to the future select where created by
future_combining_barrier, then it will only run the combiners of the input
futures until the first one of them completes.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRD7G5vihyNWuA4URAsXnAJ9T2L1HVs08S2lfw4DEbEKLuj5WrwCeKSI/
ECL+rJ1JKZQeUgRl0lmuZAw=
=pw1w
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 13:02 pm, Peter Dimov wrote:
> That aside, I'm not sure why you need future_value semantics. Let's assume
> that one has a primitive
>
>     future<R> async( F f, A1 a1, ..., An an );
>
> that schedules bind(f,a1,a2,...,an) for execution. It wouldn't be hard to
> make it recognize when Ai is future<Bi>

Oh, I came up with a reason that having future_value objects as inputs can be  
preferable to the solution you describe.  Your solution forces the "lifted"
functions to always take templates arguments.  But template methods can't be
made virtual.  Also, you can't pass them to bind() without manually
specifying all the template parameters.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRElJ5vihyNWuA4URAhRkAJ9LaXtCBzMOQnC7QuMHdchQqs27owCg6gIv
SeowJjoPt+Fy4CJwjKRoXJE=
=wkfT
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Peter Dimov-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess:

> On Monday 02 June 2008 13:02 pm, Peter Dimov wrote:
>> That aside, I'm not sure why you need future_value semantics. Let's
>> assume
>> that one has a primitive
>>
>>     future<R> async( F f, A1 a1, ..., An an );
>>
>> that schedules bind(f,a1,a2,...,an) for execution. It wouldn't be hard to
>> make it recognize when Ai is future<Bi>
>
> Oh, I came up with a reason that having future_value objects as inputs can
> be
> preferable to the solution you describe.  Your solution forces the
> "lifted"
> functions to always take templates arguments.  But template methods can't
> be
> made virtual.  Also, you can't pass them to bind() without manually
> specifying all the template parameters.

Hm. I'm not sure I follow. Let's say that I have:

struct A
{
    virtual int f( long x ) = 0;
};

int g();

future<int> h( A* pa )
{
    return async( &A::f, pa, async( g ) );
}

What's the problem with the outer async recognizing that its third argument
is a future and treating it as a dependency?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Peter Dimov-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess:
> However, the William's future does not currently support any
> multi-multiwait.
> Its wait_for_all and wait_for_any do not return futures but block when
> called.  The Gaskill futures do have operator|| and operator&& but they
> are
> not efficient enough to build a scheduler on.

I think that wait_for_any would be enough for such a scheduler. In
pseudocode, the dependency-resolving thread would do something like the
following, in a loop:

set< future<void> > waiting_, ready_;

wait_for_any( waiting_ );

// for_each in waiting_
//    if ready() move to ready_

// for each pending target
//    if dependencies are a subset of ready_, move to exec queue

// garbage-collect ready_ in some way :-)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 15:42 pm, Peter Dimov wrote:

> >
> > Oh, I came up with a reason that having future_value objects as inputs
> > can be
> > preferable to the solution you describe.  Your solution forces the
> > "lifted"
> > functions to always take templates arguments.  But template methods can't
> > be
> > made virtual.  Also, you can't pass them to bind() without manually
> > specifying all the template parameters.
>
> Hm. I'm not sure I follow. Let's say that I have:
>
> struct A
> {
>     virtual int f( long x ) = 0;
> };
>
> int g();
>
> future<int> h( A* pa )
> {
>     return async( &A::f, pa, async( g ) );
> }
>
> What's the problem with the outer async recognizing that its third argument
> is a future and treating it as a dependency?

That's interesting, is this async stuff from an existing library somewhere, or
is it a hypothetical interface?  I don't see any problem with it.
 
I was thinking of a virtual active object class, like:

struct ActiveA
{
        virtual future_value<int> f( future_value<long> x ) = 0;
};

I believe your solution could be used to achieve similar effects, but it is a
very different interface.  I'm not saying my interface is the only way to
skin the cat, just that I want to be able to implement the interface I prefer
and make it work as well as possible.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRFsx5vihyNWuA4URAtQ0AKDK/MKpUzFJuAUk/yUhxxUkuny3MQCfdBNu
KYeis+VWtWRuNzABJcqrbx8=
=NJKJ
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Updated version of futures library

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Monday 02 June 2008 15:58 pm, Peter Dimov wrote:
> I think that wait_for_any would be enough for such a scheduler. In
> pseudocode, the dependency-resolving thread

I didn't mention it, but I was thinking of a scheduler picking method requests
and dispatching them using a single thread.  At one extreme, you could create
a thread that returns a future and then blocks on wait_for_any/wait_for_all
in order to implement something that acts like future_select or
future_combining_barrier, but it's less than ideal.

> would do something like the
> following, in a loop:
>
> set< future<void> > waiting_, ready_;
>
> wait_for_any( waiting_ );

A scheduler which takes O(N) to dispatch a method request is considered
inefficient.  N being the number of pending method requests in the scheduler.  
The call to wait_for_any alone is O(N), thus my motivation for using
future_selector for a scheduler.  I'll let you in on a dirty secret: the
scheduler I'm using now is O(N), but I'd hate not to be able to improve it to
something respectable when I need to.

>
> // for_each in waiting_
> //    if ready() move to ready_
>
> // for each pending target
> //    if dependencies are a subset of ready_, move to exec queue
>
> // garbage-collect ready_ in some way :-)
>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIRF8+5vihyNWuA4URAj9LAJ4lsjOLJp0MvElF+rrgAg2DXl35UQCgoJH/
1RUsOThKBrKVFjBJL026jUM=
=fgK/
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
< Prev | 1 - 2 - 3 | Next >