Boost logo

Boost :

Subject: Re: [boost] Review Request: Variadic Macro Data library
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-21 18:47:42


On Mon, Feb 21, 2011 at 6:40 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> wrote:
> On Mon, Feb 21, 2011 at 2:37 PM, Paul Mensonides <pmenso57_at_[hidden]> wrote:
>> On Mon, 21 Feb 2011 12:57:05 -0500, Edward Diener wrote:
>>
>>> On 2/21/2011 3:57 AM, Paul Mensonides wrote:
>>
>>>> Another way to provide comfort is via education.  Hardcore pp-
>>>> metaprogramming knowledge is not required for this.
>>>
>>> Providing function-like syntax for invoking a macro with a variable
>>> number of parameters, as an alternative to pp-lib data syntax, is
>>> important to end-users and library developers if just for the sake of
>>> familiarity and regularity. A programmer using a "call" syntax which may
>>> be a macro or a function is not going to stop and say: this is a
>>> function so I can call it as 'somefunction(a,b,c)', this is a macro and
>>> therefore I must call it as 'somemacro((a,b,c))'. Instead he will ask
>>> that the same syntax be applied to both. You seem to feel this is wrong
>>> and that someone invoking a macro should realize that it is a macro (
>>> and normally does because it is capital letters ) and therefore be
>>> prepared to use a different syntax, but I think that regularity in this
>>> respect is to be valued.
>>
>> Most C/C++ developers perceive macro expansion mechanics to be similar to
>> function call mechanics.  I.e. where a user "calls" a macro A, and that
>> macro "calls" the macro B, the macro B "returns" something, which is, in
>> turn "returned" by A.  That is fundamentally *not* how macro expansion
>> behaves.  The perceived similarity, where there is none (going all the
>> way back to way before preprocessor metaprogramming) is how developers
>> have gotten into so much trouble on account of macros.
>>
>> I take serious issue with anything that intentionally perpetuates this
>> mentality.  It is one thing if the syntax required is the same by
>> coincidence.  It's another thing altogether when something is done to
>> intentionally make it so.
>
> It might be useful to discuss this topic using the Boost.Local
> `PARAMS` macro as an example.
>
> IMO, the following syntax is better from a pp metaprogramming
> prospective because the arguments are a proper pp data structure
> (i.e., a sequence) and it is very clear from the syntax that you are
> invoking a macro:
>
> int BOOST_LOCAL_FUNCTION_PARAMS( (int x) (const bind this) ) { // [1]
>    ...
> } BOOST_LOCAL_FUNCTION_NAME(l)
> l(-1);
>
> However, from the users' prospective the following syntax is preferred
> because it looks more like a C++ function parameter declaration so
> they are more familiar with it:
>
> int BOOST_LOCAL_FUNCTION_PARAMS(int x, const bind this) { // [2]
>    ...
> } BOOST_LOCAL_FUNCTION_NAME(l)
> l(-1);
>
> Therefore, as a pp metaprogrammer I'd prefer [1] but as the
> Boost.Local library developer I must keep in mind my users' preference
> and also provide [2] when variadics are available.
>
> On Mon, Feb 21, 2011 at 2:37 PM, Paul Mensonides <pmenso57_at_[hidden]> wrote:
>> I'm not terribly opposed to just BOOST_PP_TO_TUPLE(...), etc..
>>
>> #define BOOST_PP_TO_TUPLE(...) (__VA_ARGS__)
>> #define BOOST_PP_TO_ARRAY(...) \
>>    (BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_TO_TUPLE(__VA_ARGS__) \
>>    /**/
>>    // BTW, an "array" is a pointless data structure
>>    // when you have variadics, but whatever
>> #define BOOST_PP_TO_LIST(...) \
>>    BOOST_PP_TUPLE_TO_LIST((__VA_ARGS__)) \
>>    /**/
>> #define BOOST_PP_TO_SEQ(...) \
>>    BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)) \
>>    /**/
>>
>> I'm a lot more opposed to going back from a proper data structure to an
>> "argument list".
>
> IMO, it would be nice if Boost.Preprocessor supported variadics to
> make metaprogramming [2] easy. However, that does not necessarily mean
> providing:
>
> BOOST_PP_VARIADIC_TUPLE(...)
>
> I would find having these two macros just as useful (and perhaps more correct):
>
> #define BOOST_PP_TO_TUPLE(...) (__VA_ARGS__)
> BOOST_PP_TUPLE((...))
>
> Then at some point in my pp metaprogram, I will have
> `BOOST_PP_TUPLE(BOOST_PP_TO_TUPLE(__VA_ARGS__))` which would be as
> convenient for me (a pp metaprogrammer) to use as
> `BOOST_PP_TUPLE(__VA_ARGS__)` directly. Of course, the
> `BOOST_PP_TO_TUPLE(__VA_ARGS__)` invocation will be hidden inside
> `BOOST_LOCAL_FUNCTION_PARAMS(...)` expansion to respect my library
> users' request that the `PARAMS` macro invocation should look like a
> normal C++ function parameter declaration as much as possible.
>
> In summary, I would think that providing `BOOST_PP_TO_TUPLE(...)` and
> `BOOST_PP_TUPLE((...))` is a good approach.

Sorry, when I said `BOOST_PP_VARIADIC_TUPLE(...)` and
`BOOST_PP_TUPLE((...))` I meant of course
`BOOST_PP_VARIADIC_TUPLE_TO_SEQ(...)` and
`BOOST_PP_TUPLE_TO_SEQ((...))` (or some other pp tuple macro but
without the size argument).

-- 
Lorenzo

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