Need for BOOST_PP_VARIADIC_POP_FRONT

Hi, I consider using Boost.PP variadic macros support, but I seems to be missing subject macro (with support for zero arguments). Any chance we can one? I'd hate to reinvent the wheel. Regards, Gennadiy

On 11/8/2011 6:49 PM, Gennadiy Rozental wrote:
Hi,
I consider using Boost.PP variadic macros support, but I seems to be missing subject macro (with support for zero arguments).
Any chance we can one? I'd hate to reinvent the wheel.
What is it supposed to do ? My mindreading skills are in abeyance. Eddie Diener

Edward Diener <eldiener <at> tropicsoft.com> writes:
On 11/8/2011 6:49 PM, Gennadiy Rozental wrote:
Hi,
I consider using Boost.PP variadic macros support, but I seems to be missing subject macro (with support for zero arguments).
Any chance we can one? I'd hate to reinvent the wheel.
What is it supposed to do ? My mindreading skills are in abeyance.
Err... It should pop/drop first element from __VA_ARGS__ (if any). The same semantic as std container's pop_front is. Gennadiy

On 11/10/2011 4:09 AM, Gennadiy Rozental wrote:
Edward Diener<eldiener<at> tropicsoft.com> writes:
On 11/8/2011 6:49 PM, Gennadiy Rozental wrote:
Hi,
I consider using Boost.PP variadic macros support, but I seems to be missing subject macro (with support for zero arguments).
Any chance we can one? I'd hate to reinvent the wheel.
What is it supposed to do ? My mindreading skills are in abeyance.
Err... It should pop/drop first element from __VA_ARGS__ (if any). The same semantic as std container's pop_front is.
Do you mean that it would return the variadic data without the first element ?

Variadic data is not a true data structure and should not be supported as such. Therefore, it should not have a POP_FRONT, for example. Convert it into a real data structure (such as a sequence) and then do your processing on that data structure. -Paul

Paul Mensonides <pmenso57 <at> comcast.net> writes:
Variadic data is not a true data structure and should not be supported as such. Therefore, it should not have a POP_FRONT, for example. Convert it into a real data structure (such as a sequence) and then do your processing on that data structure.
How would it help me if I want to take first arguments from __VA_ARGS__ and pass the rest to the different variadic macro? Gennadiy

On 11/13/2011 11:05 AM, Gennadiy Rozental wrote:
Paul Mensonides<pmenso57<at> comcast.net> writes:
Variadic data is not a true data structure and should not be supported as such. Therefore, it should not have a POP_FRONT, for example. Convert it into a real data structure (such as a sequence) and then do your processing on that data structure.
How would it help me if I want to take first arguments from __VA_ARGS__ and pass the rest to the different variadic macro?
First I would say that it would be better internally to pass a PP sequence to your different macro rather than variadic data. But if you want to do it the way you say above, just convert the variadic data to a PP sequnce using BOOST_PP_VARIADIC_TO_SEQ, pop the first element from the sequence using BOOST_PP_SEQ_POP_FRONT, convert the sequence back to variadic data using BOOST_PP_SEQ_ENUM, and pass that data as your variadic data. In my VMD library and the work I did with Paul in adding variadic data to the preprocessor code on the trunk, I always mentioned that I viewed C++ variadic data as an easier to use interface for end-users but that Boost PP has much richer data types internally. That is why I believe the functionality regarding variadic data should be limited because Boost PP already has much richer functionality for its data types. Eddie

Edward Diener <eldiener <at> tropicsoft.com> writes:
On 11/13/2011 11:05 AM, Gennadiy Rozental wrote:
Paul Mensonides<pmenso57<at> comcast.net> writes:
Variadic data is not a true data structure and should not be supported as such. Therefore, it should not have a POP_FRONT, for example. Convert it into a real data structure (such as a sequence) and then do your processing on that data structure.
How would it help me if I want to take first arguments from __VA_ARGS__ and pass the rest to the different variadic macro?
First I would say that it would be better internally to pass a PP sequence to your different macro rather than variadic data.
And what if the second macro is part of public interface as well?
But if you want to do it the way you say above, just convert the variadic data to a PP sequnce using BOOST_PP_VARIADIC_TO_SEQ, pop the first element from the sequence using BOOST_PP_SEQ_POP_FRONT, convert the sequence back to variadic data using BOOST_PP_SEQ_ENUM, and pass that data as your variadic data.
That's good. Why not wrap it all into a simple macro that does it all?
In my VMD library and the work I did with Paul in adding variadic data to the preprocessor code on the trunk, I always mentioned that I viewed C++ variadic data as an easier to use interface for end-users but that Boost PP has much richer data types internally.
That's the core issue: variadic data provides better interface. And do not see why we should discourage use of it. I believe it should be supported completely with all the necessary interfaces. Internally we should be free to convert back and forth between variadic data and PP data structures, but it's implementation detail. Regards, Gennadiy

On 11/13/2011 12:47 PM, Gennadiy Rozental wrote:
Edward Diener<eldiener<at> tropicsoft.com> writes:
On 11/13/2011 11:05 AM, Gennadiy Rozental wrote:
Paul Mensonides<pmenso57<at> comcast.net> writes:
Variadic data is not a true data structure and should not be supported as such. Therefore, it should not have a POP_FRONT, for example. Convert it into a real data structure (such as a sequence) and then do your processing on that data structure.
How would it help me if I want to take first arguments from __VA_ARGS__ and pass the rest to the different variadic macro?
First I would say that it would be better internally to pass a PP sequence to your different macro rather than variadic data.
And what if the second macro is part of public interface as well?
Then use another macro internally that uses PP tuples, seqs, or lists.
But if you want to do it the way you say above, just convert the variadic data to a PP sequnce using BOOST_PP_VARIADIC_TO_SEQ, pop the first element from the sequence using BOOST_PP_SEQ_POP_FRONT, convert the sequence back to variadic data using BOOST_PP_SEQ_ENUM, and pass that data as your variadic data.
That's good. Why not wrap it all into a simple macro that does it all?
Because I would only be duplicating endless functionality which the other Boost PP data types already have.
In my VMD library and the work I did with Paul in adding variadic data to the preprocessor code on the trunk, I always mentioned that I viewed C++ variadic data as an easier to use interface for end-users but that Boost PP has much richer data types internally.
That's the core issue: variadic data provides better interface. And do not see why we should discourage use of it. I believe it should be supported completely with all the necessary interfaces. Internally we should be free to convert back and forth between variadic data and PP data structures, but it's implementation detail.
I agree that it provides an easier to use interface for the end user. But I strongly disagree that it is a better interface than the other Boost PP data types. Eddie

Edward Diener <eldiener <at> tropicsoft.com> writes:
That's good. Why not wrap it all into a simple macro that does it all?
Because I would only be duplicating endless functionality which the other Boost PP data types already have.
We duplicating functionality for 4 different data types already.
That's the core issue: variadic data provides better interface. And do not see why we should discourage use of it. I believe it should be supported completely with all the necessary interfaces. Internally we should be free to convert back and forth between variadic data and PP data structures, but it's implementation detail.
I agree that it provides an easier to use interface for the end user. But I strongly disagree that it is a better interface than the other Boost PP data types.
I feel like we are playing with the words. If you have an option to provide interface like this: FOO((a)(b)(c)) or this: FOO( a, b, c ) which one would you prefer, find easier, more convenient, better? I expect variadic based interfaces to become quite popular in near future and eventually prevail over any other kinds of macro based interfaces (in cases where one truly want variable number of macro arguments). Boost PP library should treat it like a first class citizen as well. Internally we might want to convert variadic data in a different collection type to perform some advanced data massaging, but not always Regards, Gennadiy

On Mon, 14 Nov 2011 04:49:47 +0000, Gennadiy Rozental wrote:
Edward Diener <eldiener <at> tropicsoft.com> writes:
That's good. Why not wrap it all into a simple macro that does it all?
Because I would only be duplicating endless functionality which the other Boost PP data types already have.
We duplicating functionality for 4 different data types already.
Yes, and only two of them are good, sequences and tuples. Of those two, tuples are only good for small (usually disjoint) data sets. Sequences are far superior in most respects. In fact, if the pp-lib had real variadic support, tuple usage almost goes away completely. This is due to the single largest type of tuple usage-- passing multiple pieces of auxiliary information through higher order algorithms and then decoding it via TUPLE_ELEM. With real variadic support, algorithms such as (e.g.) REPEAT which is currently defined as REPEAT(count, macro, data) would be altered to be REPEAT(count, macro, ...). Similarly, SEQ_FOR_EACH which is currently defined as SEQ_FOR_EACH(macro, data, seq) would be altered to be SEQ_FOR_EACH(macro, seq, ...). Doing this drastically decreases TUPLE_ELEM clutter.
I agree that it provides an easier to use interface for the end user. But I strongly disagree that it is a better interface than the other Boost PP data types.
I feel like we are playing with the words. If you have an option to provide interface like this:
FOO((a)(b)(c))
or this:
FOO( a, b, c )
which one would you prefer, find easier, more convenient, better?
The first one is better, they are both just as easy, and the latter is more convenient depending on the types of data. The problem with the second one is that it doesn't scale--just like passing around variadic data via variadic templates (with or without perfect forwarding) doesn't scale.
I expect variadic based interfaces to become quite popular in near future and eventually prevail over any other kinds of macro based interfaces (in cases where one truly want variable number of macro arguments).
That may be true for trivial user interfaces. It won't be true for a heavy-duty preprocessor metaprogramming library because it is misguided and doesn't scale. Good is not defined by the popularity.
Boost PP library should treat it like a first class citizen as well. Internally we might want to convert variadic data in a different collection type to perform some advanced data massaging, but not always
No. First-class support for variadics in the pp-lib would not take this form, and it wouldn't take this form even if other, better uses of variadic data didn't exist. Variadic data is not a good data structure and doesn't scale. Regards, Paul Mensonides

Paul Mensonides <pmenso57 <at> comcast.net> writes:
FOO((a)(b)(c))
or this:
FOO( a, b, c )
which one would you prefer, find easier, more convenient, better?
The first one is better, they are both just as easy, and the latter is more convenient depending on the types of data. The problem with the second one is that it doesn't scale--just like passing around variadic data via variadic templates (with or without perfect forwarding) doesn't scale.
Well, I find the second one better, easier and more convenient - and that's what I intend to use and present for my users. Very few people will need anything beyond basic use cases and these should be the most straightforward. As for scaling I am not sure what you mean. Would you care to show an example? Gennadiy

On Mon, 14 Nov 2011 10:57:27 +0000, Gennadiy Rozental wrote:
As for scaling I am not sure what you mean. Would you care to show an example?
Here's the list that I gave Eric when he asked me previously in regards to variadic templates, but really these are true for all forms of variadics. 1) If forces a particular argument order. It either tends to break symmetries or tends to require argument orders to change on many things. I.e. not only is the argument order forced for the variadic interface, it tends to be viral and therefore a maintenance disaster. 2) It does not play well with overloading (via number of arguments with macros, specialization of templates, or function overloading). 3) It frequently destroys the ability to use default arguments. 4) It does not work when multiple data structures need to be passed. 5) It removes the ability to use the single variadic data for other stuff. 6) Non-delimited data structures such as this cannot nest. 7) In the particular context of macros, it cannot contain elements that contain "open" commas such as class template instantiations with multiple arguments. Currently, sequences in the pp-lib cannot do this either, but that is the result of their current definition. Non-unary sequences (such as (a, b)(c, d)(e, f)) can be specified and truly variadic sequences (such as (a)(b, c)(d, e, f)) can also be specified (the difference relates to the way that the "elements" of the sequence need to be passed on to other macros). The best ways that variadics can be used is for initialization of some kind or for "functions" that have no depth (i.e. do not rely on other variadic public or private interfaces--e.g. things like min and max). Variadics can also be used effectively as a mechanism to pass "opaque" argument sets through other algorithms or through other functions (e.g. perfect forwarding). Of particular note in this latter case is that the actual (ultimate) target of those arguments is not variadic which implies that from a user standpoint, it outer interface isn't truly variadic only certain numbers and types of arguments will usually work. The effect is simply an implementation mechanism to forward to an overload set without replicating the overload set. This has slightly less context in C++11 due to lambdas' ability to easily encode such information directly. Regards, Paul Mensonides

On Tue, Nov 8, 2011 at 3:49 PM, Gennadiy Rozental <rogeeff@gmail.com> wrote:
(with support for zero arguments).
If we're talking about C99 variadic macros, then (IIRC) variadic arguments *must* contain at least one element. In other words: given #define FOO(x, ...) /* impl */, FOO("only one") is not allowed. (But perhaps I'm simply missing what you mean by variadic; if so, disregard this message.) -- GMan, Nick Gorski

GMan <gmannickg <at> gmail.com> writes:
(with support for zero arguments).
If we're talking about C99 variadic macros, then (IIRC) variadic arguments *must* contain at least one element.
Do you mean according to standard? Can you provide reference
In other words: given #define FOO(x, ...) /* impl */, FOO("only one") is not allowed.
All compilers, which I have access to, allow it. Gennadiy

On Thu, Nov 10, 2011 at 8:21 AM, Gennadiy Rozental <rogeeff@gmail.com>wrote:
Do you mean according to standard? Can you provide reference
Nope, because one doesn't exist. :) I went to look it up this morning, and I was thinking of a different problem; my apologies. -- GMan, Nick Gorski

On 11/10/2011 11:21 AM, Gennadiy Rozental wrote:
GMan<gmannickg<at> gmail.com> writes:
(with support for zero arguments).
If we're talking about C99 variadic macros, then (IIRC) variadic arguments *must* contain at least one element.
Do you mean according to standard? Can you provide reference
In the Ansi C 1999 spec 6.10.3 paragraph 12 reads: "If there is a ... in the identifier-list in the macro definition, then the trailing arguments, including any separating comma preprocessing tokens, are merged to form a single item: the variable arguments. The number of arguments so combined is such that, following merger, the number of arguments is one more than the number of parameters in the macro definition (excluding the ...)." If we have a variadic macro: #define VAR_MACRO(...) __VA_ARGS__ and we invoke it as: VAR_MACRO() The number of parameters in the macro definition ( excluding the ... ) is 0, therefore the number of arguments must be 1, as being one more than the parameters. But clearly the number of arguments is 0.
participants (4)
-
Edward Diener
-
Gennadiy Rozental
-
GMan
-
Paul Mensonides