From: William E. Kempf (wekempf_at_[hidden])
Date: 2003-02-06 12:33:15
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(),
> 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. An asynchronous
call can be bound to this result more than once.
2) You're still hiding the thread creation. 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). 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;
pool.dispatch(bind(res1.call(foo), a, b, c));
pool.dispatch(bind(res2.call(foo), d, e, f));
d = res1.value() + res2.value();
> 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.
>> as evidenced by the questions I've raised here,
> Can't argue with user confusion I guess ;-)
>> but worth considering. Not sure I care for "spawn(foo)(a, b, c)"
>> though. I personally still prefer explicit usage of Boost.Bind or some
>> other binding/lambda library. But if you want to "hide" the binding,
>> why not just "spawn(foo, a, b, c)"?
> Mostly agree; it's just that interfaces like that tend to obscure which
> is the function and which is the argument list.
OK. That's never bothered me, though, and is not the syntax used by
boost::bind, so I find it less appealing.
>> > This approach doesn't get the asynchronous call wound up with the
>> meaning of the "thread" concept.
>> If I fully understand it, yes it does, but too a lesser extent. What
>> I mean by this is that the async_result hides the created thread
>> (though you do get access to it through the res.thread() syntax).
> 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. ;)
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.
>> 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.
-- William E. Kempf wekempf_at_[hidden]
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk