Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-06-19 07:09:16


Hi Jonathan,

Jonathan Turkanis wrote:
> Hi,
>
> Here's my review of the function types submission. I'm sorry I waited until the
> last minute to submit my review.
>
> I vote to accept the library, even though I have some problems with the design.
>

Thank you for your review and for the positive vote.

>>What is your evaluation of the design?
>
>
> My main criticism is that the metafunctions taking tags are given too prominent
> a place in the library. I would rather have the library provide a collection
> metafunctions to handle the most common combinations of tags and provide the
> more generic metafunctions for 'advanced' use.
>
> For example, I'd like to have metafunctions 'is_[plain_]function_type,'
> 'is_function_pointer,' 'is_function_reference' and
> 'is_const_member_function_pointer,' like I provided in the above mentioned
> library, in addition to 'is_function_type.' Also, I'd like to see specialized
> metafunctions for constructing (plain) function types, function pointers and
> function references, in addition to the general purpose metafunction
> 'function_type.'

Basically a set of wrappers... I like it, especially in conjunction with Dave's
request to put things into a sub namespace of boost. These expressive forms
could go into boost (given they don't collide with TypeTraits) then.

>
> Next, function_type_signature is too complex; it has too many members, and their
> specifications are hard to understand. I would like to see separate
> metafunctions which take a function type and return
>

This impression come from the fact that the documentation is currently way too
weak, especially at this point.

The primary interface of this class template is not to use most of these type
member and use this class as an MPL Sequence (I'll cite a section of previous
review discussion, which I hope explains this in more detail).

Most of these members are for optimization (saving template instantiations) so I
vote for efficieny and not putting them into wrappers.
Even though using the members of 'function_type_signature' directly is pretty
close to the gory details, I don't think it should be an implementation detail.

<CITE>

Tobias Schwinger wrote:
>John Maddock wrote:
>>
>>Reading the docs, I don't understand what function_type_signature is for,
>>especially when it's members are not recomended for general use. Should
>>this be an implementation detail?
>>
>
>
> No, but the docs need to be fixed, here.
>
> 'function_type_signature' a model of MPL Random Access sequence (even an
> "extensible" one if the synthesis part has been enabled by #including
> 'function_type.hpp').
>
> The 'kind' member is the "missing piece of information" to fully describe the
> encapsulated type (in combination with the subtypes stored in the sequence).
>
> The 'representee' member is neccessary to get the type which it (e.g. a modified
> sequence) describes.
>
> Further (what follows is a preliminary try to improve this recommendation):
>
> 'function_type_signature' can be used to achieve similar functionality as
> provided by the decomposition components.
>
> This application, however, is not recommended (*), because there is
> no implied assertion that its template argument really is a function type
> and because its type members form a less expressive interface for
> decomposistion.
>
> (*) It can be an opportunity for optimization in heavily repetitive
> situations to reduce the number of template instantiations required or
> to avoid to depend on the synthesis part of the library if an extensible
> sequence is needed which does not have to be reassembled to a function
> type.
>

</CITE>

> 1. the sequence of arguments; you might call this function_type::arguments

It already exists and is currently called 'function_type_parameters'.

Btw. I prefer the term 'parameter' over 'argument' in this context, because a
(formal) parameter constraints the argument (which is also called an actual
parameter). I.e. (translated Standardese) the argument is what is passed for a
parameter.
I know e.g. 'std::unary_function::argument_type' -- but this is not exactly the
same (I interpret it like: "please give me an argument of this type").

> 2. the sequence of arguments, including ant implicit 'this' pointer; you
> might call this function_type::effective_arguments

I've been thinking about this too already... This functionaliy has been
requested by David Abrahams, already.

Proably with a second parameter (MPL lambda expression ? enum ?) to say whether
you want a "this pointer" or a "this reference" or the undecorated type or even
stripped cv (currently cv is handled via tags, this will be changed so it is
done with a cv-qualified class type, instead). Could be practical for
'function_type_class' as well.

> 3. the sequence (return_type, [class,] arg0, ... argN). You could call this
> function_type::signature.
>
> Alternatively, the result of instantiating the templates might themselves be
> sequences.

It's like this, already. You can either use e.g:

     mpl::at< function_type_parameter<T>, I >
     mpl::at< function_type_signature<T>, I >
or
     mpl::at< typename function_type_parameter<T>::type, I >
     mpl::at< typename function_type_signature<T>::type, I >

In fact, the MPL Sequence concept requires this.

>
> Next, it's too hard too keep track of all the different tags, esp. remembering
> the order of the components of the names. Why not have a few atomic tags, and

I like the idea of atomic tags to query aspects instead of full combinations...

> let user's combine them via inheritance? E.g.,
>
> struct const_tag { };
> struct volatile_tag { };
> struct reference_tag { };
> struct variadic_tag { };
> struct stdcall_tag { };
>
> struct my_tag :
> reference_tag,
> stdcall_tag,
> ...
> { };

..making this work with inheritance, in particular, might be inefficient. though
(internally these are just MPL Integral Constant bit masks).

>
> typedef is_function_type<my_tag, T>::type result;
>

> You could define a bunch of convenience tags for common cases, but people
> wouldn't be required to learn them. This is what the iostreams library does.

This is a bit opposite to the suggestion to remove the dominant role of tags...

>
> Finally, I don't like the fact that the term 'function type' is used to refer to
> pointers and references. This is bound to cause confusion. Also, it means that
> you have to write 'plain' all over the place. In my library, I used the term
> 'signature type,' which I wasn't too happy with, but at least it was clear that
> I wasn't referring to any pre-existing category of types.
>

OK - a standard reader's issue ;-). I'm not too happy about it either
(especially the plain_ prefix sucks), but 'signature term' is not very
expressive, which is why I don't like it.

Someone out there with a better term for us ?!

Regards,

Tobias


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