[futures] composite or

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

Re: [futures] boost::futures

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 
Braddock Gaskill  wrote:

> Minor bug in the code I just posted, I left out
> b.add_callback(fa) in here.
>
> Are there any thoughts on how && and || operators should
> properly handle exceptions?

These operators should create a new (composite)future, exposing the same
interface as the (simple) futures you're composing. This composite future
should handle the exceptions in a similar way as the embedded ones, i.e.
propagate the exceptions catched in the embedded futures to the caller, as
appropriate.

Also, does your implementation of operator|| allow for constructs like f1 ||
f2 || f3 ?

Regards Hartmut


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

Re: [futures] boost::futures - AND operator

by Kowalke Oliver (QD IT PA SI) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 

> On Wed, 14 Mar 2007 07:43:47 -0400, Braddock Gaskill wrote:
> > And example of an unintrusive operator||() is below.
> > template<typename T>
> > future<T> operator||(future<T> &a, future<T> &b) {
> >   future_or<T> fa(a, b);
> >   a.add_callback(fa);
> >   return fa.p_;
> > }
>
> Minor bug in the code I just posted, I left out
> b.add_callback(fa) in here.
>
> Are there any thoughts on how && and || operators should
> properly handle exceptions?

How to handle future< int > && future< std::string > && future< my_class
>?
Should promise contain a tuple (fusion container?) for the result types?

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

Parent Message unknown [futures] boost::futures - AND operator

by Kowalke Oliver (QD IT PA SI) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> How to handle future< int > && future< std::string > && future<
my_class >?
> Should promise contain a tuple (fusion container?) for the result
types?

not hte promise - the combined future
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [futures] boost::futures - AND operator

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 
Oliver.Kowalke@... wrote:

> How to handle future< int > && future< std::string > &&
> future< my_class
> >?
> Should promise contain a tuple (fusion container?) for the
> result types?

The composed future of future<T1> || future<T2> returns a variant<T1, T2>,
and a composed future of future<T1> && future<T2> returns a tuple<T1, T2>.

Regards Hartmut


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

Re: [futures] boost::futures

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wednesday 14 March 2007 07:43 am, Braddock Gaskill wrote:
> On Wed, 14 Mar 2007 06:49:57 +0100, Oliver.Kowalke wrote:
> > In your implementation I'm missing operators for logical combination
> > of futures like it is supported by the futures implementation of
> > Thorsten Schütt (vault files).
>
> Hi Oliver,
> Yes, I would like to either add this, or merge into Schutt's
> implementation if he is interested.  And example of an unintrusive
> operator||() is below.

I have to say I really am not a big fan of needless overloading of the
languages operators like logical || and &&.  Especially when you are
overloading them with functions that really don't correspond to the
original operators.  What if I want to overload || with a function that
actually does correspond to logical or, like

Future<bool> operator||(const Future<T> &a, const Future<U> &b);


--
Frank


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

attachment0 (196 bytes) Download Attachment

Re: [futures] boost::futures

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Tuesday 13 March 2007 23:55 pm, braddock wrote:
> GOAL:
>
> Provide a definitive future implementation with the best features of the
> numerous implementations and proposals floating around, in the hopes to
> avoid multiple incompatible future implementations (coroutines, active
> objects, asio, etc).  Also, to explore the combined implementation of
> the best future concepts.

It certainly seems like a worthwhile goal.  I haven't looked at it in
detail yet but I will.  I'm sure I'll have some complaints, I mean
feedback for you soon.

> Active Object libpoet framework by Frank Mori Hess
> http://source.emptycrate.com/projects/activeobjects/
> http://www.comedi.org/projects/libpoet/index.html

Just correcting an attribution, I didn't write the library at

http://source.emptycrate.com/projects/activeobjects/

That is by Jason Turner.

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

iD8DBQFF9/lX5vihyNWuA4URAkS3AKC6ISSR+A/rpRqYbmyvCMGSH8hJ7ACgq/Sk
g9KpYqDHbVkh5jAhLyU/c/g=
=GHva
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [futures] boost::futures

by braddock :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 14 Mar 2007 07:27:06 -0500, Hartmut Kaiser wrote:
> Braddock Gaskill  wrote:
> These operators should create a new (composite)future, exposing the same
> interface as the (simple) futures you're composing. This composite future
> should handle the exceptions in a similar way as the embedded ones, i.e.
> propagate the exceptions catched in the embedded futures to the caller, as
> appropriate.

So, that would mean that for f3 = f1 || f2, if f1 propagates an exception while
f2 succeeds, f3 still propagates an exception?

> Also, does your implementation of operator|| allow for constructs like f1 ||
> f2 || f3 ?

I don't have a real implementation of composition, I posted that simple
operator|| example out to show that it can be done without any changes to the
base future<T>/promise<T> implementation, so that they can proceed more or less
independently.  I'm hoping we can make use of an existing composition
implemenation.

As I understand it, the point you riase is if you want f1 || f2 || f3 to have
the semantics of returning a future<variant<T1, T2, T3> > without modifiation
to the base future class.  I would think that could be done if
operator||(future<T1>, future<T2) actually returns a proxy class which is
implicitly convertible to a future, and properly specialized operator||
functions are provided.  I haven't given this much thought yet though.

But that raises another point with the variant/tuple semantics...if I do
f3 = f1 || f2;
f3 would then have the type future<variant<f1::type, f2::type> >.
If I then do a seperate
f5 = f3 || f4;

then does f5 have the type
future<variant<f1::type, f2::type, f4::type> >, or
future<variant<variant<f1:type, f2::type>, f4::type> >?

Should there be a seperate future_group concept to disambiguate?

Composition overloading with || or && gets very hairy or impossible if the
current proposal to have a future implicitly convertable to it's value, with
blocking, goes through.  Maybe Peter has thoughts on this.

I like the tuples/variant idea of composition, but how do you handle exceptions?

The semantics of composition still seems far less settled than the basic future
concept, at least in my mind.  Any references are appreciated, I have seen very
few.  I would like to discuss it.  

Thanks for the feedback!
Braddock Gaskill
Dockside Vision Inc



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

Re: [futures] boost::futures

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 
Braddock Gaskill wrote:

> > These operators should create a new (composite)future, exposing the
> > same interface as the (simple) futures you're composing. This
> > composite future should handle the exceptions in a similar
> way as the embedded ones, i.e.
> > propagate the exceptions catched in the embedded futures to the
> > caller, as appropriate.
>
> So, that would mean that for f3 = f1 || f2, if f1 propagates
> an exception while
> f2 succeeds, f3 still propagates an exception?

I think this is very much use case dependent and anything you code into a
library for good will hurt somebody else. So my best guess here is to
implement a policy based behavior, allowing to custimize exception handling
and propagation.

> > Also, does your implementation of operator|| allow for
> constructs like
> > f1 ||
> > f2 || f3 ?
>
> I don't have a real implementation of composition, I posted
> that simple
> operator|| example out to show that it can be done without
> any changes
> operator|| to the
> base future<T>/promise<T> implementation, so that they can
> proceed more or less independently.  I'm hoping we can make
> use of an existing composition implemenation.

The implementation of composition in the future's lib in the vault could be
used as a starting point, however from todays POV I'ld prefer to reimplement
it using Eric Nieblers excellent proto library. This simplifies the required
meta template magic considerably.

> As I understand it, the point you riase is if you want f1 ||
> f2 || f3 to have the semantics of returning a
> future<variant<T1, T2, T3> > without modifiation to the base
> future class.  I would think that could be done if
> operator||(future<T1>, future<T2) actually returns a proxy
> class which
> operator||is
> implicitly convertible to a future, and properly specialized
> operator|| functions are provided.  I haven't given this much
> thought yet though.
>
> But that raises another point with the variant/tuple
> semantics...if I do
> f3 = f1 || f2;
> f3 would then have the type future<variant<f1::type, f2::type> >.
> If I then do a seperate
> f5 = f3 || f4;
>
> then does f5 have the type
> future<variant<f1::type, f2::type, f4::type> >, or
> future<variant<variant<f1:type, f2::type>, f4::type> >?

As long as you have variants only you can flatten the structure:

   future<variant<f1::type, f2::type, f4::type> >

But as soon as you start combining || and && this isn't always possible
anymore.
Additional optimization can be done, if all futures in a operator|| sequence
return the same type, in which case you don't need to use a variant.

> Should there be a seperate future_group concept to disambiguate?

What do you mean by that?

> Composition overloading with || or && gets very hairy or
> impossible if the current proposal to have a future
> implicitly convertable to it's value, with blocking, goes
> through.  Maybe Peter has thoughts on this.

I personally don't like the idea of having the future convert implicitely to
its value type at all. I'm not sure if this can be implemented completely
fail proof without ruunning in surprising behavior.

> I like the tuples/variant idea of composition, but how do you
> handle exceptions?

As I said, you might need to use policies allowing for the user to specify
what to do with exceptions.

> The semantics of composition still seems far less settled
> than the basic future concept, at least in my mind.  Any
> references are appreciated, I have seen very few.  I would
> like to discuss it.  

Regards Hartmut

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

Re: [futures] boost::futures

by Gpderetta :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 3/14/07, Hartmut Kaiser <hartmut.kaiser@...> wrote:
> [about combining mutexes]
> But as soon as you start combining || and && this isn't always possible
> anymore.
> Additional optimization can be done, if all futures in a operator|| sequence
> return the same type, in which case you don't need to use a variant.
>

Instead of going with generalized future composition, I've tried the route of
'wait_all(<future-list>) ' and 'wait_any(<future-tuple>)'

Sure, it is less flexible than overloading || and && and permitting
complex expressions, but it is easy to implement, its behavior as a
blocking point is immediate and most importantly it is simple to
understand.  If you really need to wait for multiple futures with
complex patterns, simply use a full blown reactor (i.e. asio).

> > Should there be a seperate future_group concept to disambiguate?
>
> What do you mean by that?
>
> > Composition overloading with || or && gets very hairy or
> > impossible if the current proposal to have a future
> > implicitly convertable to it's value, with blocking, goes
> > through.  Maybe Peter has thoughts on this.
>
> I personally don't like the idea of having the future convert implicitely to
> its value type at all. I'm not sure if this can be implemented completely
> fail proof without ruunning in surprising behavior.
>

I agree. What about an optional<T> like interface for future<T>?

you can do:

  future<some_type1> a = async_op1(...);
  some_type1 xa = *a; //may block if not yet ready

or, as a more convoluted example:

  future<some_type1> a = async_op1(...);
  future<some_type2> b = async_op2(...);
  future<void> timeout = post_timer(timeout);

 while(true){
    wait_any(a, b,c)
    if(a) {
       some_type1 xa = *a; // guaranteed not to block
       // do something with xa
   }
   if(b) {
       some_type2 xb = *b; // guaranteed not to block
      // do something with xb
   }
   if((a && b) || timeout) { //no boolean operator overloading here,
just plain builtins
      a.cancel(); //no-op if already completed.
      b.cancel(); //ditto
     break;
   }
}

> > I like the tuples/variant idea of composition, but how do you
> > handle exceptions?
>

In this case wait_any could report a failed future as ready. operator*
would throw the forwarded exception.  Not sure about that though. The
futures I had implemented didn't support  exception forwarding.

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

Re: [futures] boost::futures

by Sohail Somani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> -----Original Message-----
> From: boost-bounces@...
> [mailto:boost-bounces@...] On Behalf Of Hartmut Kaiser
> Sent: Wednesday, March 14, 2007 8:52 AM
> To: boost@...
> Subject: Re: [boost] [futures] boost::futures
>
>  
> Braddock Gaskill wrote:
>
> > > These operators should create a new (composite)future,
> exposing the
> > > same interface as the (simple) futures you're composing. This
> > > composite future should handle the exceptions in a similar
> > way as the embedded ones, i.e.
> > > propagate the exceptions catched in the embedded futures to the
> > > caller, as appropriate.
> >
> > So, that would mean that for f3 = f1 || f2, if f1 propagates
> > an exception while
> > f2 succeeds, f3 still propagates an exception?
>
> I think this is very much use case dependent and anything you
> code into a
> library for good will hurt somebody else. So my best guess here is to
> implement a policy based behavior, allowing to custimize
> exception handling
> and propagation.

But if you think of it as logical or, the statement f1 || f2 || f3 says:
"I don't care which one of these actually finishes, just that one does"
just like b1 || b2 || b3 says, "This statement is true if one of b1, b2
or b3 are true". If this were policy based, it would be very confusing I
would think.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [futures] boost::futures

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tuesday 13 March 2007 23:55 pm, braddock wrote:
> I'm looking for input.  I'd be willing to add additional functionality
> needed and progress it to the point where it could be formally submitted
> into boost if there is interest.  It could perhaps be merged into the
> existing futures implementation in the vault to add combined groups,
> etc.


> -add_callback() permits arbitrary functions to be called when the future
> is set.  This is needed to build non-intrusive compound waiting
> structures, like future_groups, or to better support continuation
> scheduling concepts, as in coroutines.

I'd prefer a signal/slot to add_callback().  That is: thread_safe_signals
and moving to Boost.Signals when a thread-safe version is accepted.

> TODO:
>
> The following class of sub-type assignments should be made possible, as
> discussed by Frank Hess and Peter Dimov on the list.
>
> class A {};
> class B : public A {};
> promise<shared_ptr<B> > p;
> future<shared_ptr<A> > f(p);

That isn't what I was talking about (although I agree it should be made
possible).  But B doesn't have to be derived from A.  If you can do

A a;
B b = a;

then you should be able to do (without blocking)

promise<A> p;
future<A> fa(p);
future<B> fb = fa;

For example, if I have an active_function that returns a future<unsigned>
then I should be able to pass that return value to an active_function that
takes a future<int> as a parameter and it should "just work".

Another suggestion is to rename promise::set() (boring) to
promise::fulfill() (makes me smile).  And if there is an opportunity to
work the name "empty_promise" in as a class or a concept, that would be
clever too.

Other things I would need to replace poet::future with your future class:

-Constructing a future from another with an incompatible template type via
a user-supplied conversion function.  Useful for extracting future
elements from future containers, for example.

-Adding a promise::fulfill() that accepts a future with a compatible
template type.  The effect would be that promise::fulfill() would be
called with the value from the future when it is ready.

--
Frank


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

attachment0 (196 bytes) Download Attachment

Re: [futures] boost::futures

by Michael Marcin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Frank Mori Hess wrote:
>
> I have to say I really am not a big fan of needless overloading of the
> languages operators like logical || and &&.  Especially when you are
> overloading them with functions that really don't correspond to the
> original operators.  What if I want to overload || with a function that
> actually does correspond to logical or, like
>
> Future<bool> operator||(const Future<T> &a, const Future<U> &b);

This seems like a reasonable argument against these composition overloads.

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

Re: [futures] boost::futures

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 
Frank Mori Hess wrote:

> I have to say I really am not a big fan of needless
> overloading of the languages operators like logical || and
> &&.  Especially when you are overloading them with functions
> that really don't correspond to the original operators.  What
> if I want to overload || with a function that actually does
> correspond to logical or, like
>
> Future<bool> operator||(const Future<T> &a, const Future<U> &b);

1. Why do you would do that? Do you have a use case?
2. If you really have to do that, simply do not include the header(s)
defining the operators.

Regards Hartmut


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

Re: [futures] boost::futures

by braddock :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 14 Mar 2007 14:09:37 -0400, Frank Mori Hess wrote:
> I'd prefer a signal/slot to add_callback().  That is: thread_safe_signals
> and moving to Boost.Signals when a thread-safe version is accepted.

I would prefer a signal too, although I wanted to minimize the boost-isms in
the interface in the hope that it will be closer to whatever future concept
gets into C++0x (if any).  I'd probably expose a thread_safe_signal once
available.

> then you should be able to do (without blocking)
> promise<A> p;
> future<A> fa(p);
> future<B> fb = fa;

Does libpoet already do this?  Any advice on implementation?  I split my
future_impl from the actual value type so that I could more easily support
this, but haven't worked out the details yet.

> Another suggestion is to rename promise::set() (boring) to
> promise::fulfill() (makes me smile).  And if there is an opportunity to
> work the name "empty_promise" in as a class or a concept, that would be
> clever too.

Personally, I love your fulfill() name.  I would also prefer fail() to
set_exception()...it seems more descriptive since it is more than just an
accessor method.  I didn't want to stray TOO far from Peter's C++ language
proposal though.

If I add a default constructor to future<T>, I'll be sure to have it throw
empty_promise or empty_future if get() is called before it is initialized.
;)

> -Constructing a future from another with an incompatible template type via
> a user-supplied conversion function.  Useful for extracting future
> elements from future containers, for example.

I think I saw you mention this in another post, and hoped you would come back
with it.  Can you give me a short example of how this syntax would work that I
can work towards?
 
> -Adding a promise::fulfill() that accepts a future with a compatible
> template type.  The effect would be that promise::fulfill() would be
> called with the value from the future when it is ready.

So this effectively chains the future's?  Ie:
promise<T> p1;
future<T> f1(p1);
promise<U> p2;
future<U> f2(p2);
p2.fulfill(f1);
f2.wait(); //actually waits for f1 to complete.



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

Re: [futures] boost::futures

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wednesday 14 March 2007 15:05 pm, Hartmut Kaiser wrote:

> Frank Mori Hess wrote:
> > I have to say I really am not a big fan of needless
> > overloading of the languages operators like logical || and
> > &&.  Especially when you are overloading them with functions
> > that really don't correspond to the original operators.  What
> > if I want to overload || with a function that actually does
> > correspond to logical or, like
> >
> > Future<bool> operator||(const Future<T> &a, const Future<U> &b);
>
> 1. Why do you would do that? Do you have a use case?
Making active functions that take futures as arguments and return futures
as return values is the primary feature of libpoet.  See

http://www.comedi.org/projects/libpoet/

So the operator|| above would be used if you wanted to || two results and
pass the result of the || to another active function without blocking
waiting for the futures to become ready.  Really it was just an example
though, I'm not currently planning to implement this (although maybe I
will someday if I discover it to be useful).

> 2. If you really have to do that, simply do not include the header(s)
> defining the operators.

I don't really have to define an operator||, I could just give the function
an ordinary name.  My point is, composing futures like in Thorsten
Schütt's implementation doesn't really have to define an operator||
either.  And, if I had to choose which function had a more legitimate
claim to use operator||, I'd choose my example.

Not including the headers isn't really a solution, since it precludes the
use of the conflicting functions in the same code.

Pointless overloading isn't a good thing.   What does it buy you here?  A
pair of parenthesis.

--
Frank


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

attachment0 (196 bytes) Download Attachment

Re: [futures] boost::futures

by braddock :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 14 Mar 2007 17:47:09 +0100, Giovanni Piero Deretta wrote:
> Instead of going with generalized future composition, I've tried the route of
> 'wait_all(<future-list>) ' and 'wait_any(<future-tuple>)'

This is exactly what I personally would like to see.  I don't relish the
thought of digging out a return type or exception from a future<variant<float,
string, tuple<int, double, bool> > >.  I would just want something that wakes
me up when dinner is ready and let me figure out which of my futures are valid
or have failed, if I even care.

wait(f1 || (f2 && f3));
might be nice syntax, does actually add functionality, and is simple enough as well.

IMHO, all of this fancy blocking stuff should really be part of a larger event
framework anyway.  I'd love to throw a pair of futures together with a
non-blocking file read and a listening UDP socket, and have the wait() yeild my
thread to another task while I'm dreaming.  

But this is a far bigger problem than the future concept.  add_callback() is my
answer to disentangling future<T> from the general blocking problem.

>> I personally don't like the idea of having the future convert implicitely to
>> its value type at all.

Nor do I.  Herb Sutter has a good slide in his Concur presentation against it
as well.

> I agree. What about an optional<T> like interface for future<T>?
>   future<some_type1> a = async_op1(...);
>   some_type1 xa = *a; //may block if not yet ready

Personally, I just prefer no non-sense 'get()'.  But I'm willing to
implement whatever the general consensus is, and/or whatever gets past the
C++ language committees.

Braddock Gaskill
Dockside Vision Inc


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

Re: [futures] boost::futures

by Howard Hinnant :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mar 12, 2007, at 9:30 AM, Christopher Kohlhoff wrote:

> Hi Braddock,
>
> On Fri, 09 Mar 2007 09:05:42 -0500, "Braddock Gaskill"
> <braddock@...> said:
>> The ability to use a future with the asio::io_service in particular  
>> would
>> be quite powerful.
>
> I've attached a quick and dirty futures implementation that I wrote  
> last
> year to demonstrate how futures and asio might fit together. Unlike  
> the
> various futures proposals that are around, I prefer to keep the  
> producer
> and consumer interfaces separate. Hence I have promise<T> (producer
> interface) and future<T> (consumer interface) -- these names are
> borrowed from the Alice programming language.

I've been looking at this:

...
   future<std::string> resolve(std::string host_name)
   {
     promise<std::string> result;
     boost::asio::ip::tcp::resolver::query query(host_name, "0");
     resolver_.async_resolve(query,
         boost::bind(&Resolver::handle_resolve, this, _1, _2, result));
     return result;
   }

private:
   void handle_resolve(boost::system::error_code ec,
       boost::asio::ip::tcp::resolver::iterator iterator,
       promise<std::string> result)
   {
     if (ec)
       result.fail(boost::system::system_error(ec));
     else
       result(iterator->endpoint().address().to_string());
   }

And am somewhat disappointed that the low-level worker function needs  
to be aware of promise.

What if there existed a:

template <class R>
template <class F>
promise_functor<R, F>
promise<R>::operator()(F f);

This would be in addition to the current setter functionality in  
promise.

You could call this on a promise:  result(f) and a promise_functor<R,  
F> would be returned as the result (I'm not at all very attached to  
the name promise_functor).  Executing that functor would be roughly  
equivalent to setting the promise:

   future<std::string> resolve(std::string host_name)
   {
     promise<std::string> result;
     boost::asio::ip::tcp::resolver::query query(host_name, "0");
     resolver_.async_resolve(query,  
result(boost::bind(&Resolver::handle_resolve, this, _1, _2)));
     return result;
   }

private:
   std::string handle_resolve(boost::system::error_code ec,
       boost::asio::ip::tcp::resolver::iterator iterator)
   {
     if (ec)
       throw boost::system::system_error(ec);
     return iterator->endpoint().address().to_string();
   }

The promise_functor adaptor would execute f under a try/catch, setting  
the promise's value on successful termination, else catching the  
exception and setting the promise's failure mode.

Variadic templates and perfect forwarding would make the  
implementation nearly painless (today it would be a pain).

Having a ready-to-run functor that can be produced from a promise  
might ease setting the promise's value with code that is (by design or  
by accident) promise-ignorant.

Just a thought, and not a fully fleshed out one.

-Howard

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

Re: [futures] boost::futures

by braddock :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 14 Mar 2007 15:50:34 -0400, Howard Hinnant wrote:
> You could call this on a promise:  result(f) and a promise_functor<R,  
> F> would be returned as the result (I'm not at all very attached to  
> the name promise_functor).  Executing that functor would be roughly  
> equivalent to setting the promise:

I believe this is similar to the 'class task' wrapper that Peter Dimov proposed
in N2096 at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2096.html

I think easy to use wrappers are a vital part of implementing future.  I'm not
sure I see a great advantage to putting the wrapper functionality directly
within the promise class constructor though.



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

Re: [futures] boost::futures

by Frank Mori Hess :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

On Wednesday 14 March 2007 15:26 pm, Braddock Gaskill wrote:
> On Wed, 14 Mar 2007 14:09:37 -0400, Frank Mori Hess wrote:

> > then you should be able to do (without blocking)
> > promise<A> p;
> > future<A> fa(p);
> > future<B> fb = fa;
>
> Does libpoet already do this?  Any advice on implementation?  I split my
> future_impl from the actual value type so that I could more easily
> support this, but haven't worked out the details yet.

Yes.  I have a future_body and a future_body_proxy class, both derived from
future_body_base.  A future_body handles the simple case of a future
waiting on a value.  A future_body_proxy observes another future_body_base
and becomes ready when the future_body_base it is observing becomes ready.  
It then sets its value by applying a conversion function to the value from
the other future_body_base.  This handles implicit conversions, and
conversions done with a user-specified conversion function.  See the
poet/future.hpp file:

http://www.comedi.org/cgi-bin/viewcvs.cgi/libpoet/poet/future.hpp

> > -Constructing a future from another with an incompatible template type
> > via a user-supplied conversion function.  Useful for extracting future
> > elements from future containers, for example.
>
> I think I saw you mention this in another post, and hoped you would come
> back with it.  Can you give me a short example of how this syntax would
> work that I can work towards?

I just have a constructor that takes an additional argument for the
conversion function.  The conversion function argument is really a
boost::function<T (const U&)> .  See

http://www.comedi.org/projects/libpoet/classpoet_1_1future.html#a3

> > -Adding a promise::fulfill() that accepts a future with a compatible
> > template type.  The effect would be that promise::fulfill() would be
> > called with the value from the future when it is ready.
>
> So this effectively chains the future's?  Ie:
> promise<T> p1;
> future<T> f1(p1);
> promise<U> p2;
> future<U> f2(p2);
> p2.fulfill(f1);
> f2.wait(); //actually waits for f1 to complete.

I think of it as chaining the promises, but yes you're understanding me
correctly.

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

iD8DBQFF+Fqm5vihyNWuA4URAkIvAJ4pAJHA8YU+HTwoNelKFN7j31amrgCfai1j
ifWPvF7GrBL8peAwCycpNGQ=
=jwST
-----END PGP SIGNATURE-----
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [futures] boost::futures

by Howard Hinnant :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mar 14, 2007, at 4:05 PM, Braddock Gaskill wrote:

> On Wed, 14 Mar 2007 15:50:34 -0400, Howard Hinnant wrote:
>> You could call this on a promise:  result(f) and a promise_functor<R,
>> F> would be returned as the result (I'm not at all very attached to
>> the name promise_functor).  Executing that functor would be roughly
>> equivalent to setting the promise:
>
> I believe this is similar to the 'class task' wrapper that Peter  
> Dimov proposed
> in N2096 at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2096.html

<nod> You caught me! :-)

> I think easy to use wrappers are a vital part of implementing  
> future.  I'm not
> sure I see a great advantage to putting the wrapper functionality  
> directly
> within the promise class constructor though.

Actually I was proposing a promise operator()(F) which returns the  
wrapper, thus keeping the wrapper data (the F) out of the promise  
class.  I.e. promise_functor is Peter's class task.  And promise is  
roughly Peter's class task with the functor stripped out of it.

The functor, the promise, and the future all need to point the same  
underlying return_value.  By having the promise create the  
return_value, and then subsequently responsible for producing the  
future and functor (or equivalently the future and functor are  
constructed from the promise), you ensure that all three "handles"  
point to the same return_value.

The template type of the functor is clumsy to have to deal with  
directly, and so it is best if that type is deduced somewhere, such as  
in a functor factory function, or a templated promise::operator().

-Howard

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
< Prev | 1 - 2 - 3 - 4 - 5 | Next >