[TTI] Review

classic Classic list List threaded Threaded
57 messages Options
123
Reply | Threaded
Open this post in threaded view
|

[TTI] Review

lcaminiti
Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
=================================================


Do you think the library should be accepted as a Boost library?
---------------------------------------------------------------

Yes, in my opinion Boost.TTI should be accepted as a Boost library.
Key points are:

1) I would essentially found this library useful as is.

2) The library should not expand its macros into the boost::tti
namespace (I give a few reasons and suggest alternatives below).

3) The library uses too many macros to provide essentially the same
functionality (with minor variations). This is confusing and the
library macro API should be simplified (I suggest a possible
simplification below).


My comments are all numbered and marked as follow:
[MUST] If these comments are not addressed, I would no longer
recommend to add this library into Boost.
[WANT] I would like to see these comments addressed but I would still
recommend to add this library into Boost even if these comments are
not addressed.
[NOTE] I do not feel strongly about these comments and the authors can
ignore these comments if they wish to do so.


What is your evaluation of the design?
--------------------------------------

1.  [MUST] The library provides too many macros (with very similar
functionality) which make the interface difficult to grasp.
The authors should take some time to try to redesign and simply the
library interface ideally reducing the number of macros.

[WANT] I would reduce the macro API to the following 5 macros (no
more, as I explain in the rest of the comments below):

   HAS_TYPE(has_mytype, mytype)
   HAS_TEMPLATE(has_mytpl, [template(...) {class|struct}] mytpl)
   HAS_MEMBER_VARIABLE(has_myvar, [static] myvar)
   HAS_MEMBER_FUNCTION(has_myfunc, [static] myfunc)
   MEMBER_TYPE(trait, name)

2.  [MUST] Expanding the metafunctions within the boost::tti namespace
presents a number of serious issues:
a) If multiple part of the program (possibly independent libraries)
use the TTI library to introspect the same name, the metafunction
names will clash.
b) The library macros can only be used at namespace scope. However, it
should be possible to use the macros also at class scope so to define
the introspection metafunctions as inner classes, etc (this is
critical for example in my application for Boost.TTI where I use it to
implement Boost.Contract and all Boost.Contract macros expand at class
scope).
The authors should address these issues.

[WANT] To address these issues, I would suggest to simply define the
metafunctions within the enclosing scope. It will be the user's
responsibility to use the macros within the correct scope (namespace,
class, etc). For example:

   template< class T >
   struct OurTemplateClass {
       BOOST_TTI_HAS_TYPE(has_mytype, _mytype) // also at class scope

       void f() {
           std::cout << has_mytype<T>::value << std::endl;
       }
   };

This should also allow to remove all the GEN/GEN_BASE macros.

3.  [MUST] The library macros prefix the specified name with _ but
this can create a symbol with double underscores __ which is reserved
by C++ (e.g., HAS_TYPE(_my_type) creates a metafunction named
boost::tti::has_type__my_type which is a reserved symbol).
The authors should address this issue.

[WANT] To address this issue (and also to reduce the number of macros
eliminating the need for separate TRAIT macros), I would suggest to
always ask the user to specify both the trait and the introspected
name (not just the introspected name) and then use the trait to name
the metafunction (as always, it is the user's responsibility to not
use reserved names). For example:

   HAS_TYPE(has_mytype, _mytype) // generates metafunc has_my_type

This should also allow to remove all the TRAIT macros.

4.  [WANT] I really think that mixing () and <> parenthesis is confusing:

   HAS_TEMPLATE_CHECK_PARAMS(MoreParameters,
       (class) (class) (int) (short) (class)
       (template <class)(int> class InnerTemplate) // confusing :(
       (class)
   )

IMO, this would be more readable as the following:

   HAS_TEMPLATE_CHECK_PARAMS(MoreParameters,
       (class) (class) (int) (short) (class)
       (template( (class) (int) ) class InnerTemplate) // ok :)
       (class)
   )

5.  [NOTE] There is no real need to use another macro ..._CHECK_PARAMS
because HAS_TEMPLATE can be reused. This would reduce the number of
macros. For example, with template parameters:

   HAS_TEMPLATE(
       template( // gives the parameters (optional)
           (class) (class) (int) (short) (class)
           (template( (class) (int) ) class InnerTemplate)
           (class)
       )
       struct MoreParameters // struct or class can be used here
   )

And the same macro without template parameters:

   HAS_TEMPLATE(MoreParameters)

6.  [NOTE] The same macros can accept both pp-sequences and variadic
pp-tuples (when variadic macros are supported). This eliminates the VM
macros reducing the number of different macros in the library API. For
example:

   HAS_TEMPLATE(
       template(
           class, class, int, short, class,
           template( class, int ) class InnerTemplate, // variadic commas
           class
       )
       struct MoreParameters
   )

I know this uses template( class, int ) instead of template< class,
int > but this way the syntaxes with and without variadics are unified
and consistent (and more readable IMO). Alternatively, you can
probably program the macro with variadic to be:

   HAS_TEMPLATE(
       template< // template< > here
           class, class, int, short, class,
           template< class, int > class InnerTemplate, // template< > here
           class
       >
       struct MoreParameters
   )

But still keep the following syntax without variadics:

   HAS_TEMPLATE(
       template( // template( ) here
           (class) (class) (int) (short) (class)
           (template( (class) (int) ) class InnerTemplate) // template( ) here
           (class)
       )
       struct MoreParameters
   )

7.  [WANT] Can the authors explain why the inner template parameter
name InnerTemplate is needed while all other template parameter names
are not needed? Is it really needed? Why I cannot do:

   HAS_TEMPLATE(
       template(
           class, class, int, short, class,
           template( class, int ) class, // no name InnerTemplate
           class
       )
       struct MoreParameters
   )

8.  [NOTE] There is no need to use a different set of macros for
static because the keyword static can be used to have the pp detect
this case. This will reduce the number of different macros. For
example:

   HAS_STATIC_MEMBER_FUNCTION(has_static_f, f)

Can be replaced by:

   HAS_MEMBER_FUNCTION(has_static_f, static f)

9.  [WANT] Why can't we always use the composite function syntax R
(C::*)(A0, A1, ...)? This is similar to the preferred notation for
Boost.Function so if possible it should be used instead of the other
notation.

As I understand it, some compilers have troubles supporting the
composite syntax. However, these compilers might not be able to
support the TTI library all together. Unless there is evidence of
compilers that can support TTI but not the composite function syntax,
I think only the composite function notation should be provided.

This should also allow to remove all the COMP macros.

10. [NOTE] I think "member variable" is a more accepted name that
"member data"-- isn't it? If so, I'd rename MEMBER_DATA to
MEMBER_VARIABLE.

11. [WANT] Is it possible to have some sort of composite syntax for
member variables? I remember reading something about this for
overloading the operator ->* to access member variables (as well as
calling member functions) but I can't double check right now... can
the authors look into this? For example:

   HAS_MEMBER_VARIABLE(has_number, number)

   has_number<T::short> // composite form for member variable?

If there exists a composite form for member variables, I would like
the generated metafunctions to use it instead of the plain form (so to
be consistent with the MEMBER_FUNCTION macros-- see comment above).

12. [WANT] Are the metafunction MTFC macros really needed? The docs
say they reduce compile-time (compared to using MPL placeholders) but
no evidence is shown to support that...

Extra macros complicate the library API so if they are provided for
reducing compile-time there should be some benchmarking showing their
benefits. If not, these macros should be removed.

[NOTE] If these macros are shown to be beneficial, I'd rename them
with a METAFUNC postfix because I find it more readable. For example:

   HAS_TYPE_METAFUNC
   HAS_MEMBER_FUNCTION_METAFUNC

13. [WANT] Are the nullary metafunctions really needed? The docs say
they simplify the syntax but no side-by-side example comparing the
syntax with and without the nullary type metafunctiosn is provided...

Unless their benefit is clearly shown, the nullary metafunctions
should be remove to simplify the library API.

14. [NOTE] I'd fully spell the header file names to improve
readability and be consistent with the macro names (which are
correctly fully spelled). For example, "member_function.hpp" instead
of "mem_fun.hpp".

15. [NOTE] I'd rather use an actual name for the library instead of
the cryptic acronym TTI (but I personally don't like the widely used
MPL neither so maybe it's just me). Maybe "intro" (for introspection),
or "mirror" (look at yourself), or "soul" (look into your soul), or
"psycho" (look into your person) ;) would be better names...


What is your evaluation of the implementation?
----------------------------------------------

16. I did not look at the implementation.


What is your evaluation of the documentation?
---------------------------------------------

17. [WANT] I'd add a "Motivating Example" in the Introduction section
to very briefly illustrate the library functionality (probably right
after the bullet list on the library functionalities). I had to go all
the way into the Nested Types section to start seeing some code... (I
was motivated just because I knew what the library does and I've used
MPL_XXX macros with SFINAE before).

18. [NOTE] I don't think you need a space before "?" in English (see
"Why the TTI Library ?", etc).

19. [WANT] Typo in "depending on how many parameters are bring passed".


What is your evaluation of the potential usefulness of the library?
-------------------------------------------------------------------

20. [NOTE] The library is very useful as is. For example, I use a
similar introspection technique in Boost.Contract as part of a
mechanism to check if a base class has a virtual function that is
being overridden so to automatically subcontract from such a base
class function.

21. [WANT] I think the docs should add an annex with a complete list
of all traits that would ideally be introspected even if they cannot
actually be introspected. For example, a table could list all traits
that would be good to introspect and then for each trait say
"introspected by this library", or "cannot be introspected in C++
because...", etc. For example, Boost.Contract could use the ability to
check if a function is public, protected, or private to simplify its
macro syntax (because only public functions shall check class
invariants).

Possible traits for introspection I can think of are: is public, is
protected, is private, is template, has these template parameters, is
explicit, is inline, is extern, is static, is virtual, is const
member, is volatile member, has these exception specifications
(throw), any more?

22. [WANT] I'd add an annex to the docs to compare this library with
other libraries (e.g., the "mirror" library?) that exist out there for
introspection (i.e., some sort of literature review). I would also
comment on possible C++ standard extensions or compiler specific
support for introspection.


Did you try to use the library? With what compiler? Did you have any problem?
-----------------------------------------------------------------------------

23. Yes, I compiled all the examples from the docs and played around
with the library a bit more. I have used GCC 4.3.4 on CygWin and I had
no issue.


How much effort did you put into your evaluation? A glance? A quick
reading? In-depth study?
--------------------------------------------------------------------------------------------

24. I'd say in between a quick reading and an in-depth study. I spent
about 12 hours total reading the docs, trying the examples, and
writing this review.


Are you knowledgeable about the problem domain?
-----------------------------------------------

25. I have used SFINAE before to introspect if a class has a given
inner class to implement subcontracting for Boost.Contract.
Furthermore, I have used template metaprogramming in a number of
occasions.

Overall, I'd say that I am familiar with the problem domain but I am
not an expert.


--Lorenzo
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
> Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
> =================================================
>
>
> Do you think the library should be accepted as a Boost library?
> ---------------------------------------------------------------
>
> Yes, in my opinion Boost.TTI should be accepted as a Boost library.

Appreciated !

> Key points are:
>
> 1) I would essentially found this library useful as is.
>
> 2) The library should not expand its macros into the boost::tti
> namespace (I give a few reasons and suggest alternatives below).
>
> 3) The library uses too many macros to provide essentially the same
> functionality (with minor variations). This is confusing and the
> library macro API should be simplified (I suggest a possible
> simplification below).

I will answer each of your points below rather than generally answering
2) or 3) above.

>
>
> My comments are all numbered and marked as follow:
> [MUST] If these comments are not addressed, I would no longer
> recommend to add this library into Boost.
> [WANT] I would like to see these comments addressed but I would still
> recommend to add this library into Boost even if these comments are
> not addressed.
> [NOTE] I do not feel strongly about these comments and the authors can
> ignore these comments if they wish to do so.
>
>
> What is your evaluation of the design?
> --------------------------------------
>
> 1.  [MUST] The library provides too many macros (with very similar
> functionality) which make the interface difficult to grasp.
> The authors should take some time to try to redesign and simply the
> library interface ideally reducing the number of macros.
>

I will give my reasons for each of the macros in answer to your
suggestions below, but I completely agree that if the number of macros
could be simplified and still offer the same basic functionality it
should be done.

> [WANT] I would reduce the macro API to the following 5 macros (no
> more, as I explain in the rest of the comments below):
>
>     HAS_TYPE(has_mytype, mytype)
>     HAS_TEMPLATE(has_mytpl, [template(...) {class|struct}] mytpl)

I can look into combining the various template macros if it can be done.
Currently there are three variations, disregarding the complex form of
each macro. The variations are:

BOOST_TTI_HAS_TEMPLATE(name)
BOOST_TTI_HAS_TEMPLATE_CHECK_PARAMS(name,pp-seq-of params)
BOOST_TTI_VM_HAS_TEMPLATE_CHECK_PARAMS(name,variadic-sequence-of-params)

You would like to see a single macro, called BOOST_TTI_HAS_TEMPLATE,
which could alternately take a pp-seq-of params or a
variadic-sequence-of-params. I agree that would be wonderful if it could
be done.

To do this the compiler must support variadic macros AFAICS. What if the
end-user's compiler does not do so ? Even if the end-user's compiler
supports variadic macros, how do I tell the difference between a pp-seq
of params and a variadic-sequence of params ?

So here are my thoughts. If I supported the single macro for compilers
which support variadic macros, I still need to support the two
non-variadic macro versions for compilers which do not support variadic
macros.

For the variadic macro version I can find out that is the
variadic-sequence-of-params if it has more than one variadic parameter
after the name. If it only has one variadic parameter after the name I
can check if the parameter starts with a set of parens and, if it does,
it is the pp-seq of params, else it is the variadic-sequence of params.
I think this is doable. But I still can not see my way around dropping
support completely for the non-variadic versions of this macro.

>     HAS_MEMBER_VARIABLE(has_myvar, [static] myvar)
>     HAS_MEMBER_FUNCTION(has_myfunc, [static] myfunc)

I can easily combine BOOST_TTI_HAS_MEMBER_DATA and
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into HAS_MEMBER_VARIABLE, which
covers either case, and BOOST_TTI_HAS_MEMBER_FUNCTION and
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into a HAS_MEMBER_FUNCTION, which
cover either case. But then the end-user will lose the ability to
distinguish between a 'member data/static member data' or 'member
function/static member function'. Do you really think that is the
correct thing to do just because you think there are too many macros ? I
do not.

OTOH I do not mind adding the combined member data and member function
macros as you suggested, while keeping what already exists, but then
that adds more macros ( which does not bother me a bit ), which you do
not like.

See below for my comments about the composite type functions.

>     MEMBER_TYPE(trait, name)
>
> 2.  [MUST] Expanding the metafunctions within the boost::tti namespace
> presents a number of serious issues:
> a) If multiple part of the program (possibly independent libraries)
> use the TTI library to introspect the same name, the metafunction
> names will clash.
> b) The library macros can only be used at namespace scope. However, it
> should be possible to use the macros also at class scope so to define
> the introspection metafunctions as inner classes, etc (this is
> critical for example in my application for Boost.TTI where I use it to
> implement Boost.Contract and all Boost.Contract macros expand at class
> scope).

> The authors should address these issues.

I totally agree with your criticism here and I will remove the generated
macros from any namespace. Others have also mentioned the same thing and
I immediately realized they were right when I read their reasoning.

>
> [WANT] To address these issues, I would suggest to simply define the
> metafunctions within the enclosing scope. It will be the user's
> responsibility to use the macros within the correct scope (namespace,
> class, etc). For example:
>
>     template<  class T>
>     struct OurTemplateClass {
>         BOOST_TTI_HAS_TYPE(has_mytype, _mytype) // also at class scope
>
>         void f() {
>             std::cout<<  has_mytype<T>::value<<  std::endl;
>         }
>     };
>
> This should also allow to remove all the GEN/GEN_BASE macros.

I can remove the GEN_BASE set but I would still keep the GEN set ( which
would be the same as the current GEN_BASE set ) in order to provide an
easy way to generate the metafunction name from the appropriate macro,
without the end-user having to manually remember the algorithm by which
I generate the metafunction name.

See below for my comments about generating the metafunction name.

>
> 3.  [MUST] The library macros prefix the specified name with _ but
> this can create a symbol with double underscores __ which is reserved
> by C++ (e.g., HAS_TYPE(_my_type) creates a metafunction named
> boost::tti::has_type__my_type which is a reserved symbol).
> The authors should address this issue.

You have made a good point and I can simply remove the preceding '_'
when generating the final metafunction name.

>
> [WANT] To address this issue (and also to reduce the number of macros
> eliminating the need for separate TRAIT macros), I would suggest to
> always ask the user to specify both the trait and the introspected
> name (not just the introspected name) and then use the trait to name
> the metafunction (as always, it is the user's responsibility to not
> use reserved names). For example:
>
>     HAS_TYPE(has_mytype, _mytype) // generates metafunc has_my_type
>
> This should also allow to remove all the TRAIT macros.

You want to remove functionality for automatically generating a macro
metafunction name just because you feel there are too many macros. I
believe that the automatic generation of the metafunction name is
welcomed by metaprogrammers. The MPL macros
BOOST_MPL_HAS_XXX_TEMPLATE_DEF/BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF and
BOOST_MPL_HAS_XXX_TRAIT_DEF/BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF follow the
scheme I have chosen.

>
> 4.  [WANT] I really think that mixing () and<>  parenthesis is confusing:
>
>     HAS_TEMPLATE_CHECK_PARAMS(MoreParameters,
>         (class) (class) (int) (short) (class)
>         (template<class)(int>  class InnerTemplate) // confusing :(
>         (class)
>     )
>
> IMO, this would be more readable as the following:
>
>     HAS_TEMPLATE_CHECK_PARAMS(MoreParameters,
>         (class) (class) (int) (short) (class)
>         (template( (class) (int) ) class InnerTemplate) // ok :)
>         (class)
>     )

I will look into this. It is obviously more difficult programming with
the latter than the former, but it is probably doable although with much
effort. It may not be worth the effort.

What the former syntax reflects is an exact transcription of the
template parameters with each comma replaced by ')(' and a starting and
ending parentheses. So for the template:

'template <class,class,int,class,template <class> class
InnerTemplate,class,long> struct ManyParameters { }'

the parameters are:

'(class)(class)(int)(class)(template <class> class
InnerTemplate)(class)(long)'

and all I had to do as an end-user was copy the template parameters, add
a '(' at the beginning, add a ')' at the end, and change every ',' to a
')('. As a programmer I take the sequence and directly convert it to the
template parameters via a BOOST_PP_SEQ_ENUM.

>
> 5.  [NOTE] There is no real need to use another macro ..._CHECK_PARAMS
> because HAS_TEMPLATE can be reused. This would reduce the number of
> macros. For example, with template parameters:
>
>     HAS_TEMPLATE(
>         template( // gives the parameters (optional)
>             (class) (class) (int) (short) (class)
>             (template( (class) (int) ) class InnerTemplate)
>             (class)
>         )
>         struct MoreParameters // struct or class can be used here
>     )
>
> And the same macro without template parameters:
>
>     HAS_TEMPLATE(MoreParameters)

See above for my answer to this.

>
> 6.  [NOTE] The same macros can accept both pp-sequences and variadic
> pp-tuples (when variadic macros are supported). This eliminates the VM
> macros reducing the number of different macros in the library API. For
> example:
>
>     HAS_TEMPLATE(
>         template(
>             class, class, int, short, class,
>             template( class, int ) class InnerTemplate, // variadic commas
>             class
>         )
>         struct MoreParameters
>     )
>
> I know this uses template( class, int ) instead of template<  class,
> int>  but this way the syntaxes with and without variadics are unified
> and consistent (and more readable IMO). Alternatively, you can
> probably program the macro with variadic to be:
>
>     HAS_TEMPLATE(
>         template<  // template<  >  here
>             class, class, int, short, class,
>             template<  class, int>  class InnerTemplate, // template<  >  here
>             class
>         >
>         struct MoreParameters
>     )
>
> But still keep the following syntax without variadics:
>
>     HAS_TEMPLATE(
>         template( // template( ) here
>             (class) (class) (int) (short) (class)
>             (template( (class) (int) ) class InnerTemplate) // template( ) here
>             (class)
>         )
>         struct MoreParameters
>     )

See above for my answer to this.

>
> 7.  [WANT] Can the authors explain why the inner template parameter
> name InnerTemplate is needed while all other template parameter names
> are not needed? Is it really needed? Why I cannot do:
>
>     HAS_TEMPLATE(
>         template(
>             class, class, int, short, class,
>             template( class, int ) class, // no name InnerTemplate
>             class
>         )
>         struct MoreParameters
>     )

It should not be needed. Please try without it. If it does not work I
will look and see why and attempt to correct it.

>
> 8.  [NOTE] There is no need to use a different set of macros for
> static because the keyword static can be used to have the pp detect
> this case. This will reduce the number of different macros. For
> example:
>
>     HAS_STATIC_MEMBER_FUNCTION(has_static_f, f)
>
> Can be replaced by:
>
>     HAS_MEMBER_FUNCTION(has_static_f, static f)

See above for my previous discussion on dropping the distinction between
member functions and static member functions.

>
> 9.  [WANT] Why can't we always use the composite function syntax R
> (C::*)(A0, A1, ...)? This is similar to the preferred notation for
> Boost.Function so if possible it should be used instead of the other
> notation.
>
> As I understand it, some compilers have troubles supporting the
> composite syntax. However, these compilers might not be able to
> support the TTI library all together. Unless there is evidence of
> compilers that can support TTI but not the composite function syntax,
> I think only the composite function notation should be provided.
>
> This should also allow to remove all the COMP macros.

The reason for having both a composite syntax, which you like, and the
non-composite syntax of individual types is:

1) The composite type syntax can be used when one has to pass a calling
convention, or possible some compiler-specified function-like syntax,
which the function_types 'tag' type does not support. I think this is
absolutely necessary to have.

2) The individual type syntax is there so that MEMBER_TYPE can be used
to pass a nested type which does not have to exist without causing a
compiler error. I also thin this is absolutely necessary to have.

Please read the section called 'Nested Types' in the documentation to
understand why MEMBER_TYPE is used. The ability to pass a nested type in
the form of a MEMBER_TYPE as a function parameter is very important
piece of functionality. Being able to do this for a function parameter
type or for the function return type is something I do not want to
eliminate.

>
> 10. [NOTE] I think "member variable" is a more accepted name that
> "member data"-- isn't it? If so, I'd rename MEMBER_DATA to
> MEMBER_VARIABLE.

I can understand your preference. I will consider it.

>
> 11. [WANT] Is it possible to have some sort of composite syntax for
> member variables?

There is no reason to have a composite syntax for member variables. A
member variable is a single type.

> I remember reading something about this for
> overloading the operator ->* to access member variables (as well as
> calling member functions) but I can't double check right now... can
> the authors look into this? For example:
>
>     HAS_MEMBER_VARIABLE(has_number, number)
>
>     has_number<T::short>  // composite form for member variable?
>
> If there exists a composite form for member variables, I would like
> the generated metafunctions to use it instead of the plain form (so to
> be consistent with the MEMBER_FUNCTION macros-- see comment above).
>
> 12. [WANT] Are the metafunction MTFC macros really needed? The docs
> say they reduce compile-time (compared to using MPL placeholders) but
> no evidence is shown to support that...
>
> Extra macros complicate the library API so if they are provided for
> reducing compile-time there should be some benchmarking showing their
> benefits. If not, these macros should be removed.
>
> [NOTE] If these macros are shown to be beneficial, I'd rename them
> with a METAFUNC postfix because I find it more readable. For example:
>
>     HAS_TYPE_METAFUNC
>     HAS_MEMBER_FUNCTION_METAFUNC

I supplied them merely as a convenience. In an early mailing list
message about the TTI library from Dave Abrahams, before this review, he
suggested that passing metafunctions as data as a metafunction class
would generally be faster than passing them via placeholder expressions.
I do not mind eliminating them if it seen as overkill.

>
> 13. [WANT] Are the nullary metafunctions really needed?

Functionally, no, which the documentation explicitly explains.
Syntactically I feel they are much easier to use once they are understood.

> The docs say
> they simplify the syntax but no side-by-side example comparing the
> syntax with and without the nullary type metafunctiosn is provided...
>
> Unless their benefit is clearly shown, the nullary metafunctions
> should be remove to simplify the library API.

I will add side by side examples showing the simpler syntax of using the
nullary metafunctions. I do show the different syntaxes for similar
situations in the doc, but not side by side.

Why not just ignore them if you do not like their syntax ? After all
tghey are just a set of metafunctions, which no one has to learn to use
if they do not want to do so. They do not interfere with anything else
in the library and they allow specifying nested types in a syntactically
easier way.

>
> 14. [NOTE] I'd fully spell the header file names to improve
> readability and be consistent with the macro names (which are
> correctly fully spelled). For example, "member_function.hpp" instead
> of "mem_fun.hpp".

I can do that, and probably will. You have a good point.

>
> 15. [NOTE] I'd rather use an actual name for the library instead of
> the cryptic acronym TTI (but I personally don't like the widely used
> MPL neither so maybe it's just me). Maybe "intro" (for introspection),
> or "mirror" (look at yourself), or "soul" (look into your soul), or
> "psycho" (look into your person) ;) would be better names...

Where would you like to see the longer name ? I certainly do not mind
calling the library Type Traits Introspection but that is quite a
mouthful. Like MPL ( for Metaprogramming Library ), TTI is easier to
remember and refer to.

>
>
> What is your evaluation of the implementation?
> ----------------------------------------------
>
> 16. I did not look at the implementation.
>
>
> What is your evaluation of the documentation?
> ---------------------------------------------
>
> 17. [WANT] I'd add a "Motivating Example" in the Introduction section
> to very briefly illustrate the library functionality (probably right
> after the bullet list on the library functionalities). I had to go all
> the way into the Nested Types section to start seeing some code... (I
> was motivated just because I knew what the library does and I've used
> MPL_XXX macros with SFINAE before).

I totally agree with you. I intend to revamp the introductory material
to make it simpler and easier to understand what the library can do, and
present some basic motivating examples.

>
> 18. [NOTE] I don't think you need a space before "?" in English (see
> "Why the TTI Library ?", etc).

You are right. I will change it. It is just my style but unnecessary.

>
> 19. [WANT] Typo in "depending on how many parameters are bring passed".

Corrected ! Thanks !

>
>
> What is your evaluation of the potential usefulness of the library?
> -------------------------------------------------------------------
>
> 20. [NOTE] The library is very useful as is. For example, I use a
> similar introspection technique in Boost.Contract as part of a
> mechanism to check if a base class has a virtual function that is
> being overridden so to automatically subcontract from such a base
> class function.
>
> 21. [WANT] I think the docs should add an annex with a complete list
> of all traits that would ideally be introspected even if they cannot
> actually be introspected. For example, a table could list all traits
> that would be good to introspect and then for each trait say
> "introspected by this library", or "cannot be introspected in C++
> because...", etc. For example, Boost.Contract could use the ability to
> check if a function is public, protected, or private to simplify its
> macro syntax (because only public functions shall check class
> invariants).
>
> Possible traits for introspection I can think of are: is public, is
> protected, is private, is template, has these template parameters, is
> explicit, is inline, is extern, is static, is virtual, is const
> member, is volatile member, has these exception specifications
> (throw), any more?

I think your possible list is too arbitrary. Most anything can be added
here.

>
> 22. [WANT] I'd add an annex to the docs to compare this library with
> other libraries (e.g., the "mirror" library?) that exist out there for
> introspection (i.e., some sort of literature review).

if there were an existing Boost library I might do it.

> I would also
> comment on possible C++ standard extensions or compiler specific
> support for introspection.

Which C++ standard ( 2003 or C++0x ) ? For the latter I still have much
to learn since it is so new.

>
>
> Did you try to use the library? With what compiler? Did you have any problem?
> -----------------------------------------------------------------------------
>
> 23. Yes, I compiled all the examples from the docs and played around
> with the library a bit more. I have used GCC 4.3.4 on CygWin and I had
> no issue.
>
>
> How much effort did you put into your evaluation? A glance? A quick
> reading? In-depth study?
> --------------------------------------------------------------------------------------------
>
> 24. I'd say in between a quick reading and an in-depth study. I spent
> about 12 hours total reading the docs, trying the examples, and
> writing this review.
>
>
> Are you knowledgeable about the problem domain?
> -----------------------------------------------
>
> 25. I have used SFINAE before to introspect if a class has a given
> inner class to implement subcontracting for Boost.Contract.
> Furthermore, I have used template metaprogramming in a number of
> occasions.
>
> Overall, I'd say that I am familiar with the problem domain but I am
> not an expert.
>
>
> --Lorenzo

Thanks very much for your review and specific comments.

Eddie Diener

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Nathan Ridge

> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>
> > HAS_MEMBER_VARIABLE(has_myvar, [static] myvar)
> > HAS_MEMBER_FUNCTION(has_myfunc, [static] myfunc)
>
> I can easily combine BOOST_TTI_HAS_MEMBER_DATA and
> BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into HAS_MEMBER_VARIABLE, which
> covers either case, and BOOST_TTI_HAS_MEMBER_FUNCTION and
> BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into a HAS_MEMBER_FUNCTION, which
> cover either case. But then the end-user will lose the ability to
> distinguish between a 'member data/static member data' or 'member
> function/static member function'. Do you really think that is the
> correct thing to do just because you think there are too many macros ? I
> do not.
>
 
I think Lorenzo was suggesting having a single macro whose
implementation checks whether the second argument starts
with the token "static"; if so it performs a check for static
functions only, otherwise it performs a check for nonstatic
functions only.
 
Checking whether a macro argument starts with a particular
token is certainly doable; see for example [1].
 
Regards,
Nate.
 
[1] http://lists.boost.org/boost-users/2011/03/66612.php     
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Joel falcou-4
In reply to this post by Edward Diener-3
On 10/07/11 22:59, Edward Diener wrote:

> I will look into this. It is obviously more difficult programming with
> the latter than the former, but it is probably doable although with much
> effort. It may not be worth the effort.
>
> What the former syntax reflects is an exact transcription of the
> template parameters with each comma replaced by ')(' and a starting and
> ending parentheses. So for the template:
>
> 'template <class,class,int,class,template <class> class
> InnerTemplate,class,long> struct ManyParameters { }'
>
> the parameters are:
>
> '(class)(class)(int)(class)(template <class> class
> InnerTemplate)(class)(long)'
>
> and all I had to do as an end-user was copy the template parameters, add
> a '(' at the beginning, add a ')' at the end, and change every ',' to a
> ')('. As a programmer I take the sequence and directly convert it to the
> template parameters via a BOOST_PP_SEQ_ENUM.
>

Dunno if it helps but nt2 has a NT2_STRIP macro adapted from a amcro
pasoted by Steven Watanabe that conditionnally remove parens around
symbols. You can then pass parameters containing comma to the
preprocessor this way :

FOO( (template<class T, class U> struct foo) )

and this way if no comma is involved

FOO( struct bar )

THe cod eis available under Boost licensing and can be incorporated w/e
your need.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
In reply to this post by Nathan Ridge
On 7/11/2011 3:26 AM, Nathan Ridge wrote:

>
>> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>>
>>> HAS_MEMBER_VARIABLE(has_myvar, [static] myvar)
>>> HAS_MEMBER_FUNCTION(has_myfunc, [static] myfunc)
>>
>> I can easily combine BOOST_TTI_HAS_MEMBER_DATA and
>> BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into HAS_MEMBER_VARIABLE, which
>> covers either case, and BOOST_TTI_HAS_MEMBER_FUNCTION and
>> BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION into a HAS_MEMBER_FUNCTION, which
>> cover either case. But then the end-user will lose the ability to
>> distinguish between a 'member data/static member data' or 'member
>> function/static member function'. Do you really think that is the
>> correct thing to do just because you think there are too many macros ? I
>> do not.
>>
>
> I think Lorenzo was suggesting having a single macro whose
> implementation checks whether the second argument starts
> with the token "static"; if so it performs a check for static
> functions only, otherwise it performs a check for nonstatic
> functions only.

Thanks for clarifying what Lorenzo meant.

It does seem to me that using 'static' in front of the variable or
function name is not as clear as simply having two different macro names.

My current solution is:

BOOST_TTI_HAS_MEMBER_FUNCTION(name)
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(name)

Lorenzo's suggested solution:

BOOST_TTI_HAS_MEMBER_FUNCTION([static] name)

Do you really think that the second solution is better ?

>
> Checking whether a macro argument starts with a particular
> token is certainly doable; see for example [1].

Yes I already know it is doable with the restricted input of a C++
identifier for the name.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
In reply to this post by Joel falcou-4
On 7/11/2011 10:12 AM, Joel falcou wrote:

> On 10/07/11 22:59, Edward Diener wrote:
>> I will look into this. It is obviously more difficult programming with
>> the latter than the former, but it is probably doable although with much
>> effort. It may not be worth the effort.
>>
>> What the former syntax reflects is an exact transcription of the
>> template parameters with each comma replaced by ')(' and a starting and
>> ending parentheses. So for the template:
>>
>> 'template <class,class,int,class,template <class> class
>> InnerTemplate,class,long> struct ManyParameters { }'
>>
>> the parameters are:
>>
>> '(class)(class)(int)(class)(template <class> class
>> InnerTemplate)(class)(long)'
>>
>> and all I had to do as an end-user was copy the template parameters, add
>> a '(' at the beginning, add a ')' at the end, and change every ',' to a
>> ')('. As a programmer I take the sequence and directly convert it to the
>> template parameters via a BOOST_PP_SEQ_ENUM.
>>
>
> Dunno if it helps but nt2 has a NT2_STRIP macro adapted from a amcro
> pasoted by Steven Watanabe that conditionnally remove parens around
> symbols.

I already know about this ( Mathias Gaunard reminded me ), and have
added it to a possible future implementation for pp-lib. The
implementation needs variadic macro support.

> You can then pass parameters containing comma to the
> preprocessor this way :
>
> FOO( (template<class T, class U> struct foo) )
>
> and this way if no comma is involved
>
> FOO( struct bar )

As long as one has variadic macro support in the compiler this can be
handled, in which case:

FOO( template<class T, class U> struct foo )

is also possible.

The issue I brought up in my answer to Lorenzo's review remains the
same: do I drop support for a macro metafunction in TTI if the compiler
does not have variadic macro support ?


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Stewart, Robert
In reply to this post by Edward Diener-3
Edward Diener wrote:
> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
> > Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
>
> > 10. [NOTE] I think "member variable" is a more accepted name
> > that "member data"-- isn't it? If so, I'd rename MEMBER_DATA
> > to MEMBER_VARIABLE.
>
> I can understand your preference. I will consider it.

They are called data members, not member variables, in C++.  Names like "member variable" come from other languages.

I don't use "member data" generally, but to me it describes data members collectively, not singularly.

I recognize the desire to keep the prefixes alike, but I'd rather see "HAS_DATA_MEMBER" to be consistent with Standard terminology.

_____
Rob Stewart                           [hidden email]
Software Engineer                     using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP  http://www.sig.com




________________________________

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/11/2011 10:56 AM, Stewart, Robert wrote:

> Edward Diener wrote:
>> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>>> Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
>>
>>> 10. [NOTE] I think "member variable" is a more accepted name
>>> that "member data"-- isn't it? If so, I'd rename MEMBER_DATA
>>> to MEMBER_VARIABLE.
>>
>> I can understand your preference. I will consider it.
>
> They are called data members, not member variables, in C++.  Names like "member variable" come from other languages.
>
> I don't use "member data" generally, but to me it describes data members collectively, not singularly.
>
> I recognize the desire to keep the prefixes alike, but I'd rather see "HAS_DATA_MEMBER" to be consistent with Standard terminology.

I agree with your remark about the normal terminology. I could have used
HAS_DATA_MEMBER and HAS_MEMBER_FUNCTION but I wanted to align the names
around a common beginning. That is why I chose HAS_MEMBER_DATA and
HAS_MEMBER_FUNCTION. Similarly HAS_STATIC_MEMBER_DATA and
HAS_STATIC_MEMBER_FUNCTION. Sometimes such mnemonic similarities (
having the same common beginnings ) is more important than other factors.

I know that this may start some long discussion about names in TTI, but
here is a general suggestion to all programmers who are ever upset about
names in a library, and does not just refer to TTI: if you do not like a
name, just create an object-like macro for your own use which takes some
name and transforms it to some other name which you like better.

Lorenzo might write the macro:

#define BOOST_TTI_HAS_MEMBER_VARIABLE BOOST_TTI_HAS_MEMBER_DATA

and you might write the macro:

#define BOOST_TTI_HAS_DATA_MEMBER BOOST_TTI_HAS_MEMBER_DATA

This is guaranteed to work without problems all the time AFAIK to
transform one name to another.

Eddie

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Joel falcou-4
In reply to this post by Edward Diener-3
See :

https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp


for the file, line 85 and after.

The point is it works without variadics and dont clutter the macro call
too much. Asking for double parens instead of spitting on , is maybe easier

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/11/2011 2:45 PM, Joel falcou wrote:
> See :
>
> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>
>
>
> for the file, line 85 and after.
>
> The point is it works without variadics

Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__

Clearly it needs variadic macro support.

I have already added a REMOVE_PARENS ( the equivalent to NT2_PP_STRIP(X)
in your URL above ) to a proposed addition to pp-lib which I am
discussing with Paul Mensonides, based on the updated variadic macro
support on which both of us worked and which is now in the Boost trunk.

My point is also that I may well be able to simplify the
BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
techniques, as Lorenzo suggested, but I do not feel correct in dropping
macro support support for compilers which do not support variadic macros
although I understand there are few of them left.

Eddie

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
Edward Diener-3 wrote
On 7/11/2011 2:45 PM, Joel falcou wrote:
> See :
>
> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>
>
>
> for the file, line 85 and after.
>
> The point is it works without variadics

Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__

Clearly it needs variadic macro support.

I have already added a REMOVE_PARENS ( the equivalent to NT2_PP_STRIP(X)
in your URL above ) to a proposed addition to pp-lib which I am
discussing with Paul Mensonides, based on the updated variadic macro
support on which both of us worked and which is now in the Boost trunk.

My point is also that I may well be able to simplify the
BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
techniques, as Lorenzo suggested, but I do not feel correct in dropping
macro support support for compilers which do not support variadic macros
although I understand there are few of them left.
I will later reply to all your comments on my review but let me quickly clarify a couple of things.

My suggestion was to have the *same* macro TTI_TEMPLATE handle *both* variadics tupletes and sequences. The pp skeleton code will go something like:

#if VARIADICS

#define TTI_TEMPLATE_VA_(...) \
    TTI_TEMPLATE_SEQ_(VA_TUPLE_TO_SEQ(__VA_ARGS__))

#define TTI_TEMPLATE(...) \
    BOOST_PP_IIF(IS_VARIADIC(__VA_ARGS__), \
        TTI_TEMPLATE_VA_ \
    , \
        TTI_TEMPLATE_SEQ_ \
    )(__VA_ARGS__)

#else // variadics

#define TTI_TEMPLATE(seq) TTI_TEMPLATE_SEQ_(seq)

#endif // variadics

Take a look at BOOST_LOCAL_FUNCTION_PARAMS at:
http://svn.boost.org/svn/boost/sandbox/local/boost/local/function.hpp

This macro could be expanded to also detect a single token and accept the trait parameters in front. The full grammar will then read something like:

TTI_TEMPLATE(trait, [tpl_signature_ {class | struct }] name)

If the compiler supports variadics:

tpl_signature_:
    tpl_signature_va_ | tpl_signature_seq_ // you can use either variadics or sequences :)

If not:

tpl_signature_:
    tpl_signature_seq_ // you must use sequences (because variadiacs are not supported)

Where:

tpl_signature_seq_:
    template( (class | typename | type_identifier | tpl_signature_seq_) ... ) // the pp-seq

tpl_signature_va_:
    template< {class | typename | type_identifier | tpl_signature_seq_} ... > // the pp-variadic tuple

Where lexical conventions are:
    [token] := token is optional
    token1 | token 2 := either token1 or token2
    {expr} := the token(s) resulting from the inner expression epxr
    (tokens) ... := repeat tokens within parenthesis one or more times (tokens) (tokens) etc
    tokens ... := repeat tokens separated by commas one or more times tokens, tokens etc

I think this should be possible but usually the devil is in the details... so I don't know unless someone tries to implement it :)

The real question still stands: Would this be a better interface for TTI_TEMPLATE? (You know my opinion is yes, but that's just my opinion.)

Please ask questions and let me know if I am not able to explain myself.

--Lorenzo
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
In reply to this post by Edward Diener-3
Edward Diener-3 wrote
On 7/11/2011 10:56 AM, Stewart, Robert wrote:
> Edward Diener wrote:
>> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>>> Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
>>
>>> 10. [NOTE] I think "member variable" is a more accepted name
>>> that "member data"-- isn't it? If so, I'd rename MEMBER_DATA
>>> to MEMBER_VARIABLE.
>>
>> I can understand your preference. I will consider it.
>
> They are called data members, not member variables, in C++.  Names like "member variable" come from other languages.
>
> I don't use "member data" generally, but to me it describes data members collectively, not singularly.
>
> I recognize the desire to keep the prefixes alike, but I'd rather see "HAS_DATA_MEMBER" to be consistent with Standard terminology.

I agree with your remark about the normal terminology. I could have used
HAS_DATA_MEMBER and HAS_MEMBER_FUNCTION but I wanted to align the names
around a common beginning. That is why I chose HAS_MEMBER_DATA and
HAS_MEMBER_FUNCTION. Similarly HAS_STATIC_MEMBER_DATA and
HAS_STATIC_MEMBER_FUNCTION. Sometimes such mnemonic similarities (
having the same common beginnings ) is more important than other factors.

I know that this may start some long discussion about names in TTI, but
here is a general suggestion to all programmers who are ever upset about
names in a library, and does not just refer to TTI: if you do not like a
name, just create an object-like macro for your own use which takes some
name and transforms it to some other name which you like better.

Lorenzo might write the macro:

#define BOOST_TTI_HAS_MEMBER_VARIABLE BOOST_TTI_HAS_MEMBER_DATA

and you might write the macro:

#define BOOST_TTI_HAS_DATA_MEMBER BOOST_TTI_HAS_MEMBER_DATA

This is guaranteed to work without problems all the time AFAIK to
transform one name to another.
My comment #10 started by asking if member variable is the common name. As it has been pointed out, it is not. From Stroustrup C.12 (page 853) "data member" is the common name so I think MEMBER_DATA is the appropriate name and the one I would like to use (this discussion is about the name that the C++ standard uses, not the name I like).

BTW, still from Stroustrup C.12 (page 853) there exist a composite form from data members, not just member functions:

typedef void (C::* member_func_type)(int);
typedef const char* C::* member_var_type;

So back to my comment #11, I would like to see:

    TTI_MEMBER_DATA(has_number, number)

    has_number<int T::*> // [1]

Instead of:

    has_number<T, int> [2]

Again, I would only provide the composite form for checking member functions (my comment #9) and for consistency I would only provide [1] (not [2]) for data members (my comment #11).

Thanks,
--Lorenzo
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/11/2011 5:17 PM, lcaminiti wrote:

>
> Edward Diener-3 wrote:
>>
>> On 7/11/2011 10:56 AM, Stewart, Robert wrote:
>>> Edward Diener wrote:
>>>> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>>>>> Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
>>>>
>>>>> 10. [NOTE] I think "member variable" is a more accepted name
>>>>> that "member data"-- isn't it? If so, I'd rename MEMBER_DATA
>>>>> to MEMBER_VARIABLE.
>>>>
>>>> I can understand your preference. I will consider it.
>>>
>>> They are called data members, not member variables, in C++.  Names like
>>> "member variable" come from other languages.
>>>
>>> I don't use "member data" generally, but to me it describes data members
>>> collectively, not singularly.
>>>
>>> I recognize the desire to keep the prefixes alike, but I'd rather see
>>> "HAS_DATA_MEMBER" to be consistent with Standard terminology.
>>
>> I agree with your remark about the normal terminology. I could have used
>> HAS_DATA_MEMBER and HAS_MEMBER_FUNCTION but I wanted to align the names
>> around a common beginning. That is why I chose HAS_MEMBER_DATA and
>> HAS_MEMBER_FUNCTION. Similarly HAS_STATIC_MEMBER_DATA and
>> HAS_STATIC_MEMBER_FUNCTION. Sometimes such mnemonic similarities (
>> having the same common beginnings ) is more important than other factors.
>>
>> I know that this may start some long discussion about names in TTI, but
>> here is a general suggestion to all programmers who are ever upset about
>> names in a library, and does not just refer to TTI: if you do not like a
>> name, just create an object-like macro for your own use which takes some
>> name and transforms it to some other name which you like better.
>>
>> Lorenzo might write the macro:
>>
>> #define BOOST_TTI_HAS_MEMBER_VARIABLE BOOST_TTI_HAS_MEMBER_DATA
>>
>> and you might write the macro:
>>
>> #define BOOST_TTI_HAS_DATA_MEMBER BOOST_TTI_HAS_MEMBER_DATA
>>
>> This is guaranteed to work without problems all the time AFAIK to
>> transform one name to another.
>>
>
> My comment #10 started by asking if member variable is the common name. As
> it has been pointed out, it is not. From Stroustrup C.12 (page 853) "data
> member" is the common name so I think MEMBER_DATA is the appropriate name
> and the one I would like to use (this discussion is about the name that the
> C++ standard uses, not the name I like).
>
> BTW, still from Stroustrup C.12 (page 853) there exist a composite form from
> data members, not just member functions:
>
> typedef void (C::* member_func_type)(int);
> typedef const char* C::* member_var_type;
>
> So back to my comment #11, I would like to see:
>
>      TTI_MEMBER_DATA(has_number, number)
>
>      has_number<int T::*>  // [1]
>
> Instead of:
>
>      has_number&lt;T, int&gt; [2]

Your editor messed things up, so I assume you meant:

'has_number<T, int>; [2]' just above.

The problem is that your preferred syntax [1] does not allow the result
from MEMBER_TYPE to be passed separately as a single type, whereas [2]
does allow it.

Please try reading my explanation in the documentation again about
MEMBER_TYPE, why it is so useful, and and therefore why syntax which
allows individual types to be passed should always be preferred. If,
after looking at that again in the doc, you do not understand what I am
getting at, i will be glad to explain it in this thread. I admit that my
explanation for MEMBER_TYPE may not be the clearest and easiest to
understand and in the revised doc I will be explaining it in a simpler
and hopefully easier to under manner.

>
> Again, I would only provide the composite form for checking member functions
> (my comment #9) and for consistency I would only provide [1] (not [2]) for
> data members (my comment #11).

Again if you understand MEMBER_TYPE and for what it is used, you will
understand the weakness of purely composite forms in TTI.

Eddie

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
Edward Diener-3 wrote
On 7/11/2011 5:17 PM, lcaminiti wrote:
>
> Edward Diener-3 wrote:
>>
>> On 7/11/2011 10:56 AM, Stewart, Robert wrote:
>>> Edward Diener wrote:
>>>> On 7/10/2011 7:59 PM, Lorenzo Caminiti wrote:
>>>>> Review of Boost.TTI 2011-07-10 (Lorenzo Caminiti)
>>>>
>>>>> 10. [NOTE] I think "member variable" is a more accepted name
>>>>> that "member data"-- isn't it? If so, I'd rename MEMBER_DATA
>>>>> to MEMBER_VARIABLE.
>>>>
>>>> I can understand your preference. I will consider it.
>>>
>>> They are called data members, not member variables, in C++.  Names like
>>> "member variable" come from other languages.
>>>
>>> I don't use "member data" generally, but to me it describes data members
>>> collectively, not singularly.
>>>
>>> I recognize the desire to keep the prefixes alike, but I'd rather see
>>> "HAS_DATA_MEMBER" to be consistent with Standard terminology.
>>
>> I agree with your remark about the normal terminology. I could have used
>> HAS_DATA_MEMBER and HAS_MEMBER_FUNCTION but I wanted to align the names
>> around a common beginning. That is why I chose HAS_MEMBER_DATA and
>> HAS_MEMBER_FUNCTION. Similarly HAS_STATIC_MEMBER_DATA and
>> HAS_STATIC_MEMBER_FUNCTION. Sometimes such mnemonic similarities (
>> having the same common beginnings ) is more important than other factors.
>>
>> I know that this may start some long discussion about names in TTI, but
>> here is a general suggestion to all programmers who are ever upset about
>> names in a library, and does not just refer to TTI: if you do not like a
>> name, just create an object-like macro for your own use which takes some
>> name and transforms it to some other name which you like better.
>>
>> Lorenzo might write the macro:
>>
>> #define BOOST_TTI_HAS_MEMBER_VARIABLE BOOST_TTI_HAS_MEMBER_DATA
>>
>> and you might write the macro:
>>
>> #define BOOST_TTI_HAS_DATA_MEMBER BOOST_TTI_HAS_MEMBER_DATA
>>
>> This is guaranteed to work without problems all the time AFAIK to
>> transform one name to another.
>>
>
> My comment #10 started by asking if member variable is the common name. As
> it has been pointed out, it is not. From Stroustrup C.12 (page 853) "data
> member" is the common name so I think MEMBER_DATA is the appropriate name
> and the one I would like to use (this discussion is about the name that the
> C++ standard uses, not the name I like).
>
> BTW, still from Stroustrup C.12 (page 853) there exist a composite form from
> data members, not just member functions:
>
> typedef void (C::* member_func_type)(int);
> typedef const char* C::* member_var_type;
>
> So back to my comment #11, I would like to see:
>
>      TTI_MEMBER_DATA(has_number, number)
>
>      has_number<int T::*>  // [1]
>
> Instead of:
>
>      has_number<T, int> [2]

Your editor messed things up, so I assume you meant:

'has_number<T, int>; [2]' just above.

The problem is that your preferred syntax [1] does not allow the result
from MEMBER_TYPE to be passed separately as a single type, whereas [2]
does allow it.

Please try reading my explanation in the documentation again about
MEMBER_TYPE, why it is so useful, and and therefore why syntax which
allows individual types to be passed should always be preferred. If,
after looking at that again in the doc, you do not understand what I am
getting at, i will be glad to explain it in this thread. I admit that my
explanation for MEMBER_TYPE may not be the clearest and easiest to
understand and in the revised doc I will be explaining it in a simpler
and hopefully easier to under manner.

>
> Again, I would only provide the composite form for checking member functions
> (my comment #9) and for consistency I would only provide [1] (not [2]) for
> data members (my comment #11).

Again if you understand MEMBER_TYPE and for what it is used, you will
understand the weakness of purely composite forms in TTI.
OK, I see. I remember you mentioned about MEMBER_TYPE in replying to my review and that is why you wanted to keep the non-composite member function macros. I did read the MEMBER_TYPE docs. I think I understand the issue but I need to think about it more.

I will let you know.
--Lorenzo
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
In reply to this post by lcaminiti
On 7/11/2011 5:02 PM, lcaminiti wrote:

>
> Edward Diener-3 wrote:
>>
>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>> See :
>>>
>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>
>>>
>>>
>>> for the file, line 85 and after.
>>>
>>> The point is it works without variadics
>>
>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
>>
>> Clearly it needs variadic macro support.
>>
>> I have already added a REMOVE_PARENS ( the equivalent to NT2_PP_STRIP(X)
>> in your URL above ) to a proposed addition to pp-lib which I am
>> discussing with Paul Mensonides, based on the updated variadic macro
>> support on which both of us worked and which is now in the Boost trunk.
>>
>> My point is also that I may well be able to simplify the
>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>> techniques, as Lorenzo suggested, but I do not feel correct in dropping
>> macro support support for compilers which do not support variadic macros
>> although I understand there are few of them left.
>>
>
> I will later reply to all your comments on my review but let me quickly
> clarify a couple of things.
>
> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
> variadics tupletes and sequences.

I did understand it, and I am willing to do that, but of course it needs
variadic macro support in the compiler. But what do you think I should
do if the compiler does not support variadic macros ? The possibilities are:

1) All compilers for which TTI will compile correctly support variadic
macros so don't worry about it and do nothing.

2) If the compiler does not support variadic macros, then the particular
BOOS_TTI_TEMPLATE macro and functionality can not be used, and this
needs to be documented.

3) Along with the the variadic version of BOOST_TTI_TEMPLATE which you
suggested, and which in agreeing with you I can indeed implement and
have decided to so do ( thanks for the good suggestion ), I will still
need separate versions of BOOST_TTI_TEMPLATE and
BOOST_TTI_TEMPLATE_CHECK_PARAMS for compilers which do not support
variadic macros, possibly with slightly different names.

Now you may feel that 1) or 2) are the right ways to look at things, but
I am obliged to do 3) even if it adds another macro name ( or two ) for
compilers which do not support variadic macros. This still means that I
will do as you have suggested for compilers which do support variadic
macros. So I hope my choice of 3) satisfies you while still supporting
the rare compiler user when variadic macros are not supported.

Also please remember that while most compilers support variadic macros,
some of them need a compiler switch to be turned on to do so properly,
and there are programmers who may not want to use that compiler switch.

> The pp skeleton code will go something
> like:
>
> #if VARIADICS
>
> #define TTI_TEMPLATE_VA_(...) \
>      TTI_TEMPLATE_SEQ_(VA_TUPLE_TO_SEQ(__VA_ARGS__))
>
> #define TTI_TEMPLATE(...) \
>      BOOST_PP_IIF(IS_VARIADIC(__VA_ARGS__), \
>          TTI_TEMPLATE_VA_ \
>      , \
>          TTI_TEMPLATE_SEQ_ \
>      )(__VA_ARGS__)
>
> #else // variadics
>
> #define TTI_TEMPLATE(seq) TTI_TEMPLATE_SEQ_(seq)
>
> #endif // variadics
>
> Take a look at BOOST_LOCAL_FUNCTION_PARAMS at:
> http://svn.boost.org/svn/boost/sandbox/local/boost/local/function.hpp
>
> This macro could be expanded to also detect a single token and accept the
> trait parameters in front. The full grammar will then read something like:
>
> TTI_TEMPLATE(trait, [tpl_signature_ {class | struct }] name)
>
> If the compiler supports variadics:
>
> tpl_signature_:
>      tpl_signature_va_ | tpl_signature_seq_ // you can use either variadics
> or sequences :)
>
> If not:
>
> tpl_signature_:
>      tpl_signature_seq_ // you must use sequences (because variadiacs are not
> supported)
>
> Where:
>
> tpl_signature_seq_:
>      template( (class | typename | type_identifier | tpl_signature_seq_) ...
> ) // the pp-seq
>
> tpl_signature_va_:
>      template<  {class | typename | type_identifier | tpl_signature_seq_} ...
>> // the pp-variadic tuple
>
> Where lexical conventions are:
>      [token] := token is optional
>      token1 | token 2 := either token1 or token2
>      {expr} := the token(s) resulting from the inner expression epxr
>      (tokens) ... := repeat tokens within parenthesis one or more times
> (tokens) (tokens) etc
>      tokens ... := repeat tokens separated by commas one or more times
> tokens, tokens etc
>
> I think this should be possible but usually the devil is in the details...
> so I don't know unless someone tries to implement it :)
>
> The real question still stands: Would this be a better interface for
> TTI_TEMPLATE? (You know my opinion is yes, but that's just my opinion.)
>
> Please ask questions and let me know if I am not able to explain myself.

I appreciate the code, and logic, but I can work it out for myself. My
experience working with Paul Mensonides on variadic macro support for
pp-lib has made me a much better macro coder using pp-lib, and I have
learned nearly all the good 'tricks'.

Eddie

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
Edward Diener-3 wrote
On 7/11/2011 5:02 PM, lcaminiti wrote:
>
> Edward Diener-3 wrote:
>>
>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>> See :
>>>
>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>
>>>
>>>
>>> for the file, line 85 and after.
>>>
>>> The point is it works without variadics
>>
>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
>>
>> Clearly it needs variadic macro support.
>>
>> I have already added a REMOVE_PARENS ( the equivalent to NT2_PP_STRIP(X)
>> in your URL above ) to a proposed addition to pp-lib which I am
>> discussing with Paul Mensonides, based on the updated variadic macro
>> support on which both of us worked and which is now in the Boost trunk.
>>
>> My point is also that I may well be able to simplify the
>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>> techniques, as Lorenzo suggested, but I do not feel correct in dropping
>> macro support support for compilers which do not support variadic macros
>> although I understand there are few of them left.
>>
>
> I will later reply to all your comments on my review but let me quickly
> clarify a couple of things.
>
> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
> variadics tupletes and sequences.

I did understand it, and I am willing to do that, but of course it needs
variadic macro support in the compiler. But what do you think I should
do if the compiler does not support variadic macros ? The possibilities are:
I was trying to say for compilers without variaidics (detected by BOOST_NO_VARIADIC_MACROS) you can do:

    TTI_TEMPLATE(trait, [tpl_signature_seq_ {class | struct}] name)

And for compilers with variadics you can do:

    TTI_TEMPLATE(trait, [{tpl_signature_seq_ | tpl_signature_va_} {class | struct}] name)

Can't you? (Am I missing something?)

1) All compilers for which TTI will compile correctly support variadic
macros so don't worry about it and do nothing.

2) If the compiler does not support variadic macros, then the particular
BOOS_TTI_TEMPLATE macro and functionality can not be used, and this
needs to be documented.

3) Along with the the variadic version of BOOST_TTI_TEMPLATE which you
suggested, and which in agreeing with you I can indeed implement and
have decided to so do ( thanks for the good suggestion ), I will still
need separate versions of BOOST_TTI_TEMPLATE and
BOOST_TTI_TEMPLATE_CHECK_PARAMS for compilers which do not support
variadic macros, possibly with slightly different names.

Now you may feel that 1) or 2) are the right ways to look at things, but
I am obliged to do 3) even if it adds another macro name ( or two ) for
compilers which do not support variadic macros. This still means that I
will do as you have suggested for compilers which do support variadic
macros. So I hope my choice of 3) satisfies you while still supporting
the rare compiler user when variadic macros are not supported.

Also please remember that while most compilers support variadic macros,
some of them need a compiler switch to be turned on to do so properly,
and there are programmers who may not want to use that compiler switch.

> The pp skeleton code will go something
> like:
>
> #if VARIADICS
>
> #define TTI_TEMPLATE_VA_(...) \
>      TTI_TEMPLATE_SEQ_(VA_TUPLE_TO_SEQ(__VA_ARGS__))
>
> #define TTI_TEMPLATE(...) \
>      BOOST_PP_IIF(IS_VARIADIC(__VA_ARGS__), \
>          TTI_TEMPLATE_VA_ \
>      , \
>          TTI_TEMPLATE_SEQ_ \
>      )(__VA_ARGS__)
>
> #else // variadics
>
> #define TTI_TEMPLATE(seq) TTI_TEMPLATE_SEQ_(seq)
>
> #endif // variadics
>
> Take a look at BOOST_LOCAL_FUNCTION_PARAMS at:
> http://svn.boost.org/svn/boost/sandbox/local/boost/local/function.hpp
>
> This macro could be expanded to also detect a single token and accept the
> trait parameters in front. The full grammar will then read something like:
>
> TTI_TEMPLATE(trait, [tpl_signature_ {class | struct }] name)
>
> If the compiler supports variadics:
>
> tpl_signature_:
>      tpl_signature_va_ | tpl_signature_seq_ // you can use either variadics
> or sequences :)
>
> If not:
>
> tpl_signature_:
>      tpl_signature_seq_ // you must use sequences (because variadiacs are not
> supported)
>
> Where:
>
> tpl_signature_seq_:
>      template( (class | typename | type_identifier | tpl_signature_seq_) ...
> ) // the pp-seq
>
> tpl_signature_va_:
>      template<  {class | typename | type_identifier | tpl_signature_seq_} ...
>> // the pp-variadic tuple
>
> Where lexical conventions are:
>      [token] := token is optional
>      token1 | token 2 := either token1 or token2
>      {expr} := the token(s) resulting from the inner expression epxr
>      (tokens) ... := repeat tokens within parenthesis one or more times
> (tokens) (tokens) etc
>      tokens ... := repeat tokens separated by commas one or more times
> tokens, tokens etc
>
> I think this should be possible but usually the devil is in the details...
> so I don't know unless someone tries to implement it :)
>
> The real question still stands: Would this be a better interface for
> TTI_TEMPLATE? (You know my opinion is yes, but that's just my opinion.)
>
> Please ask questions and let me know if I am not able to explain myself.

I appreciate the code, and logic, but I can work it out for myself. My
experience working with Paul Mensonides on variadic macro support for
pp-lib has made me a much better macro coder using pp-lib, and I have
learned nearly all the good 'tricks'.
Sure. BTW, if you end-up taking a look at Boost.Local and see strange things, please let me know (I'm happy to improve/fix my code if needed).

Thanks,
--Lorenzo
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/11/2011 6:25 PM, lcaminiti wrote:

>
> Edward Diener-3 wrote:
>>
>> On 7/11/2011 5:02 PM, lcaminiti wrote:
>>>
>>> Edward Diener-3 wrote:
>>>>
>>>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>>>> See :
>>>>>
>>>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>>>
>>>>>
>>>>>
>>>>> for the file, line 85 and after.
>>>>>
>>>>> The point is it works without variadics
>>>>
>>>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>>>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>>>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
>>>>
>>>> Clearly it needs variadic macro support.
>>>>
>>>> I have already added a REMOVE_PARENS ( the equivalent to NT2_PP_STRIP(X)
>>>> in your URL above ) to a proposed addition to pp-lib which I am
>>>> discussing with Paul Mensonides, based on the updated variadic macro
>>>> support on which both of us worked and which is now in the Boost trunk.
>>>>
>>>> My point is also that I may well be able to simplify the
>>>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>>>> techniques, as Lorenzo suggested, but I do not feel correct in dropping
>>>> macro support support for compilers which do not support variadic macros
>>>> although I understand there are few of them left.
>>>>
>>>
>>> I will later reply to all your comments on my review but let me quickly
>>> clarify a couple of things.
>>>
>>> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
>>> variadics tupletes and sequences.
>>
>> I did understand it, and I am willing to do that, but of course it needs
>> variadic macro support in the compiler. But what do you think I should
>> do if the compiler does not support variadic macros ? The possibilities
>> are:
>>
>
> I was trying to say for compilers without variaidics (detected by
> BOOST_NO_VARIADIC_MACROS) you can do:
>
>      TTI_TEMPLATE(trait, [tpl_signature_seq_ {class | struct}] name)
>
> And for compilers with variadics you can do:
>
>      TTI_TEMPLATE(trait, [{tpl_signature_seq_ | tpl_signature_va_} {class |
> struct}] name)
>
> Can't you? (Am I missing something?)

I do not want to stick the tpl-signature as a prefix sequence to the
name. It is ugly and confusing. For some reason you like this sort of
thing but I find it poor. Furthermore having to extract the template
parameters from the 'name' itself may be undoable even with varaiadic
macros much less with only non-variadic macros.

You have fallen in love with this sort of thing, perhaps because you
have had to do something similar your 'local' library, but I will opt
for a simpler and clearer way, even if it means a few extra macro names.

However, as you suggested, I can do:

TTI_TEMPLATE(name,pp-seq-or-variadic-template-parameters)

with variadic parameters support, and will look to implement a single
macro on that side rather than both TTI_TEMPLATE and
TTI_TEMPLATE_CHECK_PARAMS.

Eddie

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

Edward Diener-3
On 7/11/2011 7:03 PM, Edward Diener wrote:

> On 7/11/2011 6:25 PM, lcaminiti wrote:
>>
>> Edward Diener-3 wrote:
>>>
>>> On 7/11/2011 5:02 PM, lcaminiti wrote:
>>>>
>>>> Edward Diener-3 wrote:
>>>>>
>>>>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>>>>> See :
>>>>>>
>>>>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> for the file, line 85 and after.
>>>>>>
>>>>>> The point is it works without variadics
>>>>>
>>>>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>>>>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>>>>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...)
>>>>> __VA_ARGS__
>>>>>
>>>>> Clearly it needs variadic macro support.
>>>>>
>>>>> I have already added a REMOVE_PARENS ( the equivalent to
>>>>> NT2_PP_STRIP(X)
>>>>> in your URL above ) to a proposed addition to pp-lib which I am
>>>>> discussing with Paul Mensonides, based on the updated variadic macro
>>>>> support on which both of us worked and which is now in the Boost
>>>>> trunk.
>>>>>
>>>>> My point is also that I may well be able to simplify the
>>>>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>>>>> techniques, as Lorenzo suggested, but I do not feel correct in
>>>>> dropping
>>>>> macro support support for compilers which do not support variadic
>>>>> macros
>>>>> although I understand there are few of them left.
>>>>>
>>>>
>>>> I will later reply to all your comments on my review but let me quickly
>>>> clarify a couple of things.
>>>>
>>>> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
>>>> variadics tupletes and sequences.
>>>
>>> I did understand it, and I am willing to do that, but of course it needs
>>> variadic macro support in the compiler. But what do you think I should
>>> do if the compiler does not support variadic macros ? The possibilities
>>> are:
>>>
>>
>> I was trying to say for compilers without variaidics (detected by
>> BOOST_NO_VARIADIC_MACROS) you can do:
>>
>> TTI_TEMPLATE(trait, [tpl_signature_seq_ {class | struct}] name)
>>
>> And for compilers with variadics you can do:
>>
>> TTI_TEMPLATE(trait, [{tpl_signature_seq_ | tpl_signature_va_} {class |
>> struct}] name)
>>
>> Can't you? (Am I missing something?)
>
> I do not want to stick the tpl-signature as a prefix sequence to the
> name. It is ugly and confusing. For some reason you like this sort of
> thing but I find it poor. Furthermore having to extract the template
> parameters from the 'name' itself may be undoable even with varaiadic
> macros much less with only non-variadic macros.

After thinking about this, and calming down a bit ( my apologies for
getting emotional above ), it may be possible, even without variadic
macros, to distinguish between:

TTI_TEMPLATE(name)

and

TTI_TEMPLATE((pp-seq) name)

as well as extracting both the pp-seq and the name separately from the
second form. Still I will probably opt for:

TTI_TEMPLATE(name,BOOST_PP_NIL)

or

TTI_TEMPLATE(name,(pp-seq))

to distinguish between the two for non-variadic macros. I really do not
like the idea of prepending the name being looked for with the template
parameters in a single macro argument.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
In reply to this post by Edward Diener-3
On Mon, Jul 11, 2011 at 7:03 PM, Edward Diener <[hidden email]> wrote:

> On 7/11/2011 6:25 PM, lcaminiti wrote:
>>
>> Edward Diener-3 wrote:
>>>
>>> On 7/11/2011 5:02 PM, lcaminiti wrote:
>>>>
>>>> Edward Diener-3 wrote:
>>>>>
>>>>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>>>>>
>>>>>> See :
>>>>>>
>>>>>>
>>>>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>>>>
>>>>>>
>>>>>>
>>>>>> for the file, line 85 and after.
>>>>>>
>>>>>> The point is it works without variadics
>>>>>
>>>>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>>>>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>>>>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
>>>>>
>>>>> Clearly it needs variadic macro support.
>>>>>
>>>>> I have already added a REMOVE_PARENS ( the equivalent to
>>>>> NT2_PP_STRIP(X)
>>>>> in your URL above ) to a proposed addition to pp-lib which I am
>>>>> discussing with Paul Mensonides, based on the updated variadic macro
>>>>> support on which both of us worked and which is now in the Boost trunk.
>>>>>
>>>>> My point is also that I may well be able to simplify the
>>>>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>>>>> techniques, as Lorenzo suggested, but I do not feel correct in dropping
>>>>> macro support support for compilers which do not support variadic
>>>>> macros
>>>>> although I understand there are few of them left.
>>>>>
>>>>
>>>> I will later reply to all your comments on my review but let me quickly
>>>> clarify a couple of things.
>>>>
>>>> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
>>>> variadics tupletes and sequences.
>>>
>>> I did understand it, and I am willing to do that, but of course it needs
>>> variadic macro support in the compiler. But what do you think I should
>>> do if the compiler does not support variadic macros ? The possibilities
>>> are:
>>>
>>
>> I was trying to say for compilers without variaidics (detected by
>> BOOST_NO_VARIADIC_MACROS) you can do:
>>
>>     TTI_TEMPLATE(trait, [tpl_signature_seq_ {class | struct}] name)
>>
>> And for compilers with variadics you can do:
>>
>>     TTI_TEMPLATE(trait, [{tpl_signature_seq_ | tpl_signature_va_} {class |
>> struct}] name)
>>
>> Can't you? (Am I missing something?)
>
> I do not want to stick the tpl-signature as a prefix sequence to the name.
> It is ugly and confusing. For some reason you like this sort of thing but I
> find it poor. Furthermore having to extract the template parameters from the
> 'name' itself may be undoable even with varaiadic macros much less with only
> non-variadic macros.
>
> You have fallen in love with this sort of thing, perhaps because you have
> had to do something similar your 'local' library, but I will opt for a
> simpler and clearer way, even if it means a few extra macro names.

Fair enough. My comment #5 was just a NOTE so I actually really don't
feel strongly about it (and "love" would instead be a strong feeling
;) ). If I'm the only one suggesting this syntax, you should probably
ignore it.

> However, as you suggested, I can do:
>
> TTI_TEMPLATE(name,pp-seq-or-variadic-template-parameters)

Sure, my comment #6 (removing VM macros) is independent from my
comment #5 (removing CHECK_PARAMS macros).

> with variadic parameters support, and will look to implement a single macro
> on that side rather than both TTI_TEMPLATE and TTI_TEMPLATE_CHECK_PARAMS.

I'm not sure about this... wouldn't you expect the macros to be
symmetric with and without variadics? In other words, if there is a
CHECK_PARAMS without variadics, I would expect it to be a CHECK_PARAMS
also with variadics. That is because CHECK_PARAMS does not
semantically have anything to do with variadics, it is just "the macro
you use when you specify the template parameters" (variadics or not).

Thanks,
--Lorenzo
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [TTI] Review

lcaminiti
In reply to this post by Edward Diener-3
On Mon, Jul 11, 2011 at 9:11 PM, Edward Diener <[hidden email]> wrote:

> On 7/11/2011 7:03 PM, Edward Diener wrote:
>>
>> On 7/11/2011 6:25 PM, lcaminiti wrote:
>>>
>>> Edward Diener-3 wrote:
>>>>
>>>> On 7/11/2011 5:02 PM, lcaminiti wrote:
>>>>>
>>>>> Edward Diener-3 wrote:
>>>>>>
>>>>>> On 7/11/2011 2:45 PM, Joel falcou wrote:
>>>>>>>
>>>>>>> See :
>>>>>>>
>>>>>>>
>>>>>>> https://github.com/MetaScale/nt2/blob/master/modules/sdk/include/nt2/sdk/details/preprocessor.hpp
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> for the file, line 85 and after.
>>>>>>>
>>>>>>> The point is it works without variadics
>>>>>>
>>>>>> Line 87: #define NT2_PP_DETAILS_STRIP_PARENS_I(...) 1,1
>>>>>> Line 91: #define NT2_PP_DETAILS_TEST_ARITY_I(a,b,c,...) c
>>>>>> Line 96: #define NT2_PP_DETAILS_MAYBE_STRIP_PARENS_2_I(...)
>>>>>> __VA_ARGS__
>>>>>>
>>>>>> Clearly it needs variadic macro support.
>>>>>>
>>>>>> I have already added a REMOVE_PARENS ( the equivalent to
>>>>>> NT2_PP_STRIP(X)
>>>>>> in your URL above ) to a proposed addition to pp-lib which I am
>>>>>> discussing with Paul Mensonides, based on the updated variadic macro
>>>>>> support on which both of us worked and which is now in the Boost
>>>>>> trunk.
>>>>>>
>>>>>> My point is also that I may well be able to simplify the
>>>>>> BOOST_TTI_TEMPLATE macros in TTI using variadic macro support
>>>>>> techniques, as Lorenzo suggested, but I do not feel correct in
>>>>>> dropping
>>>>>> macro support support for compilers which do not support variadic
>>>>>> macros
>>>>>> although I understand there are few of them left.
>>>>>>
>>>>>
>>>>> I will later reply to all your comments on my review but let me quickly
>>>>> clarify a couple of things.
>>>>>
>>>>> My suggestion was to have the *same* macro TTI_TEMPLATE handle *both*
>>>>> variadics tupletes and sequences.
>>>>
>>>> I did understand it, and I am willing to do that, but of course it needs
>>>> variadic macro support in the compiler. But what do you think I should
>>>> do if the compiler does not support variadic macros ? The possibilities
>>>> are:
>>>>
>>>
>>> I was trying to say for compilers without variaidics (detected by
>>> BOOST_NO_VARIADIC_MACROS) you can do:
>>>
>>> TTI_TEMPLATE(trait, [tpl_signature_seq_ {class | struct}] name)
>>>
>>> And for compilers with variadics you can do:
>>>
>>> TTI_TEMPLATE(trait, [{tpl_signature_seq_ | tpl_signature_va_} {class |
>>> struct}] name)
>>>
>>> Can't you? (Am I missing something?)
>>
>> I do not want to stick the tpl-signature as a prefix sequence to the
>> name. It is ugly and confusing. For some reason you like this sort of
>> thing but I find it poor. Furthermore having to extract the template
>> parameters from the 'name' itself may be undoable even with varaiadic
>> macros much less with only non-variadic macros.
>
> After thinking about this, and calming down a bit ( my apologies for getting
> emotional above ), it may be possible, even without variadic macros, to
> distinguish between:

OK, it looks like we're exchanging messages in real-time here-- I sent
you a reply and .5 sec after I got this other message :)

> TTI_TEMPLATE(name)
>
> and
>
> TTI_TEMPLATE((pp-seq) name)
>
> as well as extracting both the pp-seq and the name separately from the
> second form. Still I will probably opt for:
>
> TTI_TEMPLATE(name,BOOST_PP_NIL)
>
> or
>
> TTI_TEMPLATE(name,(pp-seq))
>
> to distinguish between the two for non-variadic macros. I really do not like
> the idea of prepending the name being looked for with the template
> parameters in a single macro argument.

I don't think for 1 single macro argument the template prefix is
needed (see [1] below).

Let's write down some examples for what I meant with comment #5
leaving variadics (comment #6) and implementation issues a side for a
moment. Let's just try to see if (1) we understand each other and (2)
we list options that users will find to be a better interface for the
library. I will not list the trait parameter (even if I suggested to
always add it).

Here's some examples of what I was proposing with my comment #5:

// check if mytpl exist
TTI_TEMPLATE( mytpl ) // [1]

// check if template<class> struct mytpl exist
TTI_TEMPLATE( template( (class) ) struct mytpl )

// check if template<class, int> class mytpl exist
TTI_TEMPLATE( template( (class) (int) ) class mytpl )

// check if template<class, int, template<typename, class> struct>
class mytpl exist
TTI_TEMPLATE( template( (class) (int) (template( (typename) (class) )
struct) class mytpl )

The real question still is: For the TTI library user, is the interface
above better than TTI_TEMPLATE_CHECK_PARAMS? (Again, you know my
answer is yes but that's just my opinion.) I think we should all focus
the discussion in try to answer this question first.

Thanks,
--Lorenzo
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
123