
On 8/21/2010 2:58 AM, Christopher Schmidt wrote:
Joel de Guzman schrieb:
On 8/17/2010 5:10 AM, Christopher Schmidt wrote:
I think simply providing a sequence of proxies is less error-prone than trying to hide it when possible. the example I used in a previous email would then outright fail until support for proxies is added, as opposed to work in one case and fail in another, very similar, case.
Those are very good points. I await for Christopher's reply. I think what you gave is a reasonable strategy. I like it.
I don't agree. The proxy is indeed clumsy, but due to being implicitly convertible to the underlying type it does its job quite well. In most use-cases an adapted 'class' does feel just like any other regular fusion container. In my opinion, fully exposing the proxy type is not conducive as the type of interest is always the type encapsulated by the wrapper. The proxy is just a means to an end. If the special traits of proxies are ditched, that is if the implicit conversion ability is removed and the proxy is exposed as the actual value type, all generic user code will need to handle proxy types explicitly. Generic user tmp code would probably need hacky mpl-code that distinguishes fusion proxies from non-proxy value types. Generic run-time functors would need to be specialized for proxies. That is prone to errors! With the current design, only very few run-time functors have to be specialized for proxies at all.
Also very good points. I think the proxy should behave similar to Boost ref, as it should expose an implicit conversion to T. This alone will satisfy many code that expects T. As for exposing the proxy as the value type of the sequence, you are right. However, what we can probably do is to be consistent with handling const and non-const and always return a proxy so there is no surprise when code works one way and not the other way.
I agree.
Stefan, considering your special use-case: if the proxy's underlying value type is exposed as the real value type of the sequence, you don't need to specialize your functor at all. See the attached code - ref_for_each is an implementation of fusion::for_each that internally resolves proxy types. Such an approach hides the proxy completely!
I do not see how fully exposing the proxy leads to simpler or less error prone code. Therefore I vote for keeping the interface as it is - with the proxy type being documented and its semantics fully exposed to the user. As for the name, I do like ADAPT_EXPR or ADAPT_ADT more than ADAPT_CLASS.
My problem with this approach is that you need special algorithms to deal with these proxies. It may not be a bad idea to embrace proxies (and reference wrappers) library wide as intrinsic to our concepts, so that proxies will be totally transparent, but I am not quite sure if it's worth it. It's an additional burden for algorithm writers to deal with.
Well, that is a *lot* of work - and such an approach does not hide the proxy completely. The return type of fusion::deref is still a proxy.
I think we should proxify the 'const' return type and rename BOOST_FUSION_ADAPT_xxxCLASSxxx to BOOST_FUSION_ADAPT_xxxADTxxx . BOOST_FUSION_ADAPT_xxxEXPRxxx breaks ranks as EXPR does not relate to the adaptee at all. boost::fusion::extension::class_member_proxy<T> should be changed to boost::fusion::extension::adt_attribute_proxy<T, B>, with B being a boolean constant that is true for lvalue and false for rvalue proxies. The drawbacks of proxies should be pointed out explicitly in the documentation, including a short abstract that advocates adapting abstract data types using fusion's native extension mechanism in order to avoid the proxy.
Are there any objections to these changes? Stefan, is this acceptable for you?
Sounds good to me. The name adt_attribute_proxy is a bit too long though. I'd prefer a shorter name but I can't think of one yet. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net