Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-07-02 06:04:28


Hi Dave,

Your previous post has brought up a very interesting point for me:

I tried to completely specify the behaviour of the logic to give the user a
chance to fully understand it and make things more transparent. It seems to me
I've been "thinking too close to the implementation" and this approach is no good.

ANNOTATION: I'll cut your post down to only refer to what still matters based on a
conclusion drawn further below.

David Abrahams wrote:

<snip>
> Subtypes? I think you mean argument, optional class target, and
> return types. These are not (necessarily) "subtypes!" That word has
> a very specific -- and different -- meaning in computer science.
>

I see. How about "Component types?" This term should be close enough to common
terminology since we are talking about "compound types." Works?

> A type supported by this library is completely described by its
> argument types, return type, class target (if the type is a
> member pointer), and the following properties:
>
> - decoration (none,pointer,reference,member pointer)
> - variadicity
> - cv-qualification of member function pointers
> - calling convention
>

Btw: "argument types" or "parameter types?"

> You really don't intend to represent cv-qualification of member
> function pointers as simply the cv-qualification attached to the class
> type?
>

I do -- by default! Specifying these tags allows you to set/query either one of
them explicitly.

Because:

ANNOTATION: I use const_member instead of const_ because it's its new name without
trailing underscore. It will imply the 'member_pointer' decoration property then.

a)
     is_const< typename class_of<T>::type >::value
     // precondition: T must be a member function pointer (decomposition)

     is_function<T,const_member>::value
     // no precondition (classification)

b)

     mpl::not< is_const< typename class_of<T>::type > >::value
     // is lengthy

     is_function<T,non_const_member>::value
     // is not, plus it's more efficient

c)

     function_type<MemFnPtr,[non_]const_member>::type
     // remove/add const from member function

     // NOTE: not specifying the const property in the context means keeping the
     // qualification of the original type (given the destination type will be a
     // member function pointer, that is).

<snip> >> free_or_static <<
> Okay, I understand. That said, the way you are classifying these
> things is going to cause confusion. There is no distinction between
> the types of static member functions and the types of free functions.

This name was exchanged because the initial one I used ("unbound") was found to
be too unexpressive.

> There is only a distinction in how they are declared; once you are
> dealing with their types, they are the same thing. The name
> "free_or_static" carries the implication that you have precise
> (non-wildcard) tags "free" and "static". In my opinion, you should

...and also goes under "known issues", already.

> use the terms "member" and "nonmember." A pointer to a static member
> function is not a member pointer in the C++ type system; that's why my
> suggested terminology works. So "free_or_static" should be "nonmember."
>

OK. It's the best so far.

Sometimes the easiest solution seams the least obvious (not to mention that
'member' would have needed disambiguation too, caring about static members ;-) )...

>>> is_function< T, unspecified_decoration >::value
>>> // true for any type T that the library can handle
>>>
>>>[You need to say more clearly what "can handle" means. IMO the
>>>comment should really be expressed as the last sentence of the
>>>foregoing paragraph]
>>
>>s/type the library can handle/(possibly decorated) function type/
>
>
> "(possibly decorated)" adds nothing. You have already made it clear
> that function types can be decorated -- or if you haven't, you can't
> just throw the term in here in parentheses and expect anyone to
> understand what you mean.

What 'decorated' means was already introduced (by the very first sentence of the
documentation, see previous post).

Generally I agree. However in this case it /should/ be mentioned because:

     template<typename T, typename Tag = undecorated> struct is_function;
                                         ^^^^^^^^^^^

The default argument, if no tag is given, makes 'is_function' only match function
types (standard definition, compatible with TypeTraits).

The "code-to-English-mapping" is like this:

   is_function<T> // "is T a function (not decorated)?"
   is_function<T,pointer> // "is T a function pointer?"
   is_function<T,variadic> // "is the function _in_ T variadic?"

However, if too confusing I can introduce a version of 'is_function' with a
single template parameter, change the name of the current 'is_function' to
something else (e.g. "is_function_of_kind" -- better names are very welcome) and
change its default argument.

   See: http://lists.boost.org/boost/2005/06/29480.php

<snip>
>
> Ah sorry, no I was just in a hurry. Make the final sentence of the paragraph:
>
> The specialization of tag used below indicates that the resulting
> function type should be a pointer to a variadic function.
>

It's bought. With the first "function" removed, though.

<snip>
>> // Member function pointer -> function with default calling convention
>> function_type<T, tag<undecorated,unspecified_call> >::type
>
>
> Oh, wait. This use of "unspecified" is very bad, because it conflicts
> with the very specific way the C++ standard (and many Boost libraries
> as a result) use the word. The calling convention of the result isn't
> unspecified -- that would mean "it will be something whose properties
> we might describe but we're not going to tell you exactly what it is."

This issue was already expressed and "any" was proposed instead.

> In this case the calling convention is very much being specified to be
> the default!
>
> For this purpose, the proper name is "default_call."

Well "default_call" should not be a wildcard then. In classification context
"default_call" should mean "detect whether this has default calling convention" (I
had to think a moment about if these semantics are implementable -- they are).

OK -- STOP.

Can we remove the fully-general wildcards for each property from the
interface, then?

I believe we can:

   Classification:

   If you want to ignore a property just don't specify it in the query.

   Requirements: one wildcard to match any decoration /or/ to change the default
   argument of the class template currently called 'is_function' (as described
   above)

   Synthesis:

   You either override defaults or properties of an existing type.

   Requirements: there is a (in some ways special) 'default_call' calling
   convention.

>
>
>>Here the properties of the original types are overridden in an implicit tag
>>combination with the tag representing the type.
>>
>>Well, we /could/ only allow it in this very context,
>
>
> Allow what?
>

Sorry: "allow overriding of tag properties".

>
>>however, it maybe makes things more complicated to explain (see

<- (because it has to be documented anyway)

>>below) and involves more template instantiations - so I'm not sure
>>it's really worth it.

<snip>
>>
>> function_type< my_mpl_sequence, pointer > // no implicit tag combination
>>VVVVV
>> function_type< my_function , pointer > // implicit tag combination
>> function_type< signature<F> , pointer > // implicit tag combination
>>^^^^^
>>
>>I believe it is _very_ important to document this behaviour.
>
>
> Yes, the behavior should be documented, but the way you are describing
> it exposes implementation details and complicates understanding. If
> you just say that "any properties of the first argument that are not
> overridden by the second argument will be properties of the result"
> then you don't need to introduce new jargon for "implicit tag
> combination."
>

Very nice! I believe it makes sense move this sentence to the part of the
reference section on 'function_type' or 'tag'.

Thank you very much for these comments! I'll reassmeble our points to a piece of
documentation and post them later.


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