Re: [boost] [function_types]

Tobias Schwinger wrote:
Now folks complain more about the tags than before. Worse than that, I haven't been presented a single clearly superior alternative! Because there isn't one? Steven Watanabe wrote:
For both components and the synthesis metafunctions, having the result type as the first element of the sequence doesn't really make sense to me. I would expect that the return type would often need to be handled separately from the parameters in the cases where anything other than simply passing the result of components to function_type<...> is needed.
I found it preferable to have a one-type representation, but I'm currently not feeling to strong about it anymore. Your proposal might be a good idea -- I'll think about it.
I don't have anything in particular against a one type representation. It is probably quite useful. I just don't think giving an mpl sequence a special meaning is the right way to do it.
Two things:
1. How to specify the properties for type synthesis?
You proposed to strip it out, but I think that the compromising the symmetry of the library is far to high of a price for unspecified aesthetical reasons.
If the tags can't be cleanly eliminated from the synthesis
AMDG metafunctions too, then I agree completely. I can only think of two ways to do this. Neither one is completely satisfactory. 1. template<class R, class Args, class Option1, class Option2, class Option3> struct function_type : original_function_type<typename mpl::push_front<Args, R>::type, tag<Option1, Option2, Option3> > {}; 2. template<class ReturnTypeAndArgsAndTagsRolledIntoASingleType> struct function_type : ... {}; The first may be a little better, but then again it could work even with tags--in which case it is just extra syntactic sugar. The second one would basically be the inverse of components. In the second case a "constructor" for components with signature template<class R, class Args, class ... Options> would be needed.
2. The primary interface would be "shape shifting" based on the configuration:
is_fastcall_cc is_stdcall_cc is_*_cc
What about is_same<calling_convention<F>::type, fastcall_cc>?
Further: none of the reviewers (except Doug Gregor, who was talking about the issue in the very specific context of merger with another library) did answer the following question:
What's wrong with the tag types (other than personal taste) in the first place?
Anything that can be made to work with a different interface will work with the tags. So, to a large degree they are a matter of personal taste. I've had a lot of trouble trying to figure out why I didn't like them. I think it can be summarized as 1. They depart from existing (TypeTraits) usage for no particular gain. This is not really important especially since the default arguments make this invisible for the most common case and it would be very bad to forbid potential improvements just because they are different. 2. Why are they used for some things and not others? The tags are used for variadicness, constness, and calling convention, but (from a user's perspective) they are not used for member pointer vs. function vs. function pointer. 3. Why separate the return type and the parameters from everything else? I would prefer to either combine or separate EVERYTHING. That, however, is just personal taste.
A "reject" vote for a matter of personal taste is pretty tough, IMO. But sadly it wouldn't surprise me much after reading some of the material from the GIL review...
Regards,
Tobias
In Christ, Steven Watanabe

Steven Watanabe wrote:
Tobias Schwinger wrote:
What's wrong with the tag types (other than personal taste) in the first place?
Anything that can be made to work with a different interface will work with the tags. So, to a large degree they are a matter of personal taste. I've had a lot of trouble trying to figure out why I didn't like them. I think it can be summarized as
1. They depart from existing (TypeTraits) usage for no particular gain. This is not really important especially since the default arguments make this invisible for the most common case and it would be very bad to forbid potential improvements just because they are different.
I agree.
2. Why are they used for some things and not others? The tags are used for variadicness, constness, and calling convention, but (from a user's perspective) they are not used for member pointer vs. function vs. function pointer.
The previous version used tags for these properties. Further, 2 is in opposition to 1: putting the "function decoration" into tags will remove the "TypeTraits feel". All I can say is: I've been there. I came to the conclusion that simple and straightforward client code is more important -- and it really did cost me quite an effort to let go of the nagging perfectionism about consistency for consistency's sake.
3. Why separate the return type and the parameters from everything else? I would prefer to either combine or separate EVERYTHING. That, however, is just personal taste.
For the same reason I'm not at all convinced that it would really make the library better. However, these thoughts seem familiar, somehow ;-)... Thanks for taking the time to put them into words! Regards, Tobias

Steven Watanabe wrote:
AMDG
Tobias Schwinger wrote:
Now folks complain more about the tags than before. Worse than that, I haven't been presented a single clearly superior alternative!
Because there isn't one?
Maybe. I wouldn't want to claim that while I can neither prove nor disprove it. I'm just trying to show that the design is reasonable.
Steven Watanabe wrote:
For both components and the synthesis metafunctions, having the result type as the first element of the sequence doesn't really make sense to me. I would expect that the return type would often need to be handled separately from the parameters in the cases where anything other than simply passing the result of components to function_type<...> is needed.
I found it preferable to have a one-type representation, but I'm currently not feeling to strong about it anymore. Your proposal might be a good idea -- I'll think about it.
I don't have anything in particular against a one type representation. It is probably quite useful. I just don't think giving an mpl sequence a special meaning is the right way to do it.
I don't see it this way: a function is a compound type and the mpl sequence contains the component types. They are ordered left to right which seems pretty common, too.
Two things:
1. How to specify the properties for type synthesis?
You proposed to strip it out, but I think that the compromising the symmetry of the library is far to high of a price for unspecified aesthetical reasons.
If the tags can't be cleanly eliminated from the synthesis metafunctions too, then I agree completely. I can only think of two ways to do this.
I'm not sure I understand you correctly, here. To do what? Eliminate the tags? ...
Neither one is completely satisfactory. 1. template<class R, class Args, class Option1, class Option2, class Option3> struct function_type : original_function_type<typename mpl::push_front<Args, R>::type, tag<Option1, Option2, Option3> > {}; 2. template<class ReturnTypeAndArgsAndTagsRolledIntoASingleType> struct function_type : ... {};
... If so, I can't see any "tag elimination"...
The first may be a little better, but then again it could work even with tags--in which case it is just extra syntactic sugar. The second one would basically be the inverse of components. In the second case a "constructor" for components with signature template<class R, class Args, class ... Options> would be needed.
... Both alternatives even seem to increase the presence of tags in the interface ... I considered the first alternative when redesigning the library, but I chose the current design because it doesn't redundantly introduce lots of rarely needed template parameters.
2. The primary interface would be "shape shifting" based on the configuration:
is_fastcall_cc is_stdcall_cc is_*_cc
What about is_same<calling_convention<F>::type, fastcall_cc>?
... Same here: The return type of that metafunction would be a tag again, wouldn't it? Maybe I just lost track because of a missing sentence or something like that. Regards, Tobias

Steven Watanabe wrote:
AMDG
Tobias Schwinger wrote:
Now folks complain more about the tags than before. Worse than that, I haven't been presented a single clearly superior alternative!
Because there isn't one?
Maybe. I wouldn't want to claim that while I can neither prove nor disprove it. I'm just trying to show that the design is reasonable.
Steven Watanabe wrote:
For both components and the synthesis metafunctions, having the result type as the first element of the sequence doesn't really make sense to me. I would expect that the return type would often need to be handled separately from the parameters in the cases where anything other than simply passing the result of components to function_type<...> is needed.
I found it preferable to have a one-type representation, but I'm currently not feeling to strong about it anymore. Your proposal might be a good idea -- I'll think about it.
I don't have anything in particular against a one type representation. It is probably quite useful. I just don't think giving an mpl sequence a special meaning is the right way to do it.
I don't see it this way: a function is a compound type and the mpl sequence contains the component types. They are ordered left to right which seems pretty common, too.
Two things:
1. How to specify the properties for type synthesis?
You proposed to strip it out, but I think that the compromising the symmetry of the library is far to high of a price for unspecified aesthetical reasons.
If the tags can't be cleanly eliminated from the synthesis metafunctions too, then I agree completely. I can only think of two ways to do this.
I'm not sure I understand you correctly, here. To do what? Eliminate the tags? ...
Neither one is completely satisfactory. 1. template<class R, class Args, class Option1, class Option2, class Option3> struct function_type : original_function_type<typename mpl::push_front<Args, R>::type, tag<Option1, Option2, Option3> > {}; 2. template<class ReturnTypeAndArgsAndTagsRolledIntoASingleType> struct function_type : ... {};
... If so, I can't see any "tag elimination"...
The first may be a little better, but then again it could work even with tags--in which case it is just extra syntactic sugar. The second one would basically be the inverse of components. In the second case a "constructor" for components with signature template<class R, class Args, class ... Options> would be needed.
... Both alternatives even seem to increase the presence of tags in the interface ... I considered the first alternative when redesigning the library, but I chose the current design because it doesn't redundantly introduce lots of rarely needed template parameters.
2. The primary interface would be "shape shifting" based on the configuration:
is_fastcall_cc is_stdcall_cc is_*_cc
What about is_same<calling_convention<F>::type, fastcall_cc>?
... Same here: The return type of that metafunction would be a tag again, wouldn't it? Maybe I just lost track because of a missing sentence or something like that. Regards, Tobias

Steven Watanabe wrote:
Tobias Schwinger wrote:
What's wrong with the tag types (other than personal taste) in the first place?
Anything that can be made to work with a different interface will work with the tags. So, to a large degree they are a matter of personal taste. I've had a lot of trouble trying to figure out why I didn't like them. I think it can be summarized as
1. They depart from existing (TypeTraits) usage for no particular gain. This is not really important especially since the default arguments make this invisible for the most common case and it would be very bad to forbid potential improvements just because they are different.
I agree.
2. Why are they used for some things and not others? The tags are used for variadicness, constness, and calling convention, but (from a user's perspective) they are not used for member pointer vs. function vs. function pointer.
The previous version used tags for these properties. Further, 2 is in opposition to 1: putting the "function decoration" into tags will remove the "TypeTraits feel". All I can say is: I've been there. I came to the conclusion that simple and straightforward client code is more important -- and it really did cost me quite an effort to let go of the nagging perfectionism about consistency for consistency's sake.
3. Why separate the return type and the parameters from everything else? I would prefer to either combine or separate EVERYTHING. That, however, is just personal taste.
For the same reason I'm not at all convinced that it would really make the library better. However, these thoughts seem familiar, somehow ;-)... Thanks for taking the time to put them into words! Regards, Tobias
participants (2)
-
Steven Watanabe
-
Tobias Schwinger