Boost logo

Boost :

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


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.

-- 
Lorenzo

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