Boost logo

Boost :

From: Dave Abrahams (dave_at_[hidden])
Date: 2003-02-06 14:48:50


On Thursday, February 06, 2003 12:33 PM [GMT+1=CET],
William E. Kempf <wekempf_at_[hidden]> wrote:

> Dave Abrahams said:
>
> > > Hmm... that would be
> > > an interesting alternative implementation. I'm not sure it's as
> > > "obvious" as the syntax I suggested
> >
> > Sorry, IMO there's nothing "obvious" about your syntax. It looks
> > cumbersome and low-level to me. Let me suggest some other syntaxes for
> > async_result, though:
> >
> > async_call<double> later(foo, a, b, c)
> >
> > or, if you don't want to duplicate the multi-arg treatment of bind(),
> > just:
> >
> > async_call<double> later(bind(foo, a, b, c));
> > ...
> > ...
> > double d = later(); // call it to get the result out.
>
> The two things that come to mind for me with this suggestion are:
>
> 1) You've explicitly tied the result into the call. I chose the other
> design because the result is just that, only a result.

Hm? How is the result not a result in my case?

> An asynchronous call can be bound to this result more than once.

...and if it can't be default-constructed?

> 2) You're still hiding the thread creation.

Absolutely. High-level vs. low-level.

> This is a mistake to me for
> two reasons. First, it's not as obvious that a thread is being created
> here (though the new names help a lot).

Unimportant, IMO. Who cares how an async_call is implemented under the
covers?

> Second, and this is more
> important, you've bound this concept to boost::thread explicitly. With
> the fully seperated concerns of my proposal, async_result can be used with
> other asynchronous call mechanisms, such as the coming boost::thread_pool.
>
> asyc_result<double> res1, res2;
> thread_pool pool;
> pool.dispatch(bind(res1.call(foo), a, b, c));
> pool.dispatch(bind(res2.call(foo), d, e, f));
> d = res1.value() + res2.value();

This one is important. However, there are other ways to deal with this. An
async_call object could take an optional thread-creation parameter, for
example.

> > I like the first one better, but could understand why you'd want to go
> > with the second one. This is easily implemented on top of the existing
> > Boost.Threads interface. Probably any of my suggestions is.
>
> Yes, all of the suggestions which don't directly modify boost::thread are
> easily implemented on top of the existing interface.

No duh ;-)

> > That's what we mean by the terms "high-level" and "encapsulation" ;-)
>
> Yes, but encapsulation shouldn't hide the implementation to the point that
> users aren't aware of what the operations actually are. ;)

I don't think I agree with you, if you mean that the implementation should
be apparent from looking at the usage. Implementation details that must be
revealed should be shown in the documentation.

> But I'll admit that some of my own initial confusion on this particular
> case probably stem from having my brain focused on implementation details.

Ha!

> > > I found this
> > > surprising enough to require careful thought about the FULL example
> > > you posted to understand this.
> >
> > Like I said, I can't argue with user confusion. Does the name
> > "async_call" help?
>
> Certainly... but leads to the problems I addresed above. There's likely a
> design that will satisfy all concerns, however, that's not been given yet.

P'raps.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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