Boost logo

Boost :

Subject: Re: [boost] [preprocessor] Warning: Incoming
From: lcaminiti (lorcaminiti_at_[hidden])
Date: 2011-06-27 09:02:04

Paul Mensonides wrote:
> On Sun, 26 Jun 2011 11:31:55 -0400, Edward Diener wrote:
>> On 6/26/2011 10:57 AM, Lorenzo Caminiti wrote:
>>> If the pp-lib needs to be changed, why not change it radically to add
>>> ground-up variadic support? (This is not a rhetoric question. I am
>>> sincerely asking as there might be very good reasons not to add
>>> ground-up variadic support to Boost.Preprocessor.)
>> I am not sure what Paul meant by "ground-up" variadic support, nor how
>> you take it, but the variadic support in pp-lib is very much the same as
>> in my VMD library with a few added enhancements based on Paul's
>> knowledge of preprocessor programming. The overall intent in pp-lib was
>> the same as VMD: to integrate the use of variadic macros with pp-lib's
>> richer data types ( tuple, array, list, seq ) and to enhance the use of
>> pp-lib tuples with variadic macro support.
> This is a good summary of the changes.
> What I meant by "ground-up" would be effectively re-implementing
> Boost.Preprocessor from scratch with variadic macros and placemarkers in
> mind. For example, with decent preprocessors (something we don't have as
> a rule), this would drastically reduce the number of use cases for
> BOOST_PP_TUPLE_ELEM. The use case I'm specifically thinking of at the
> moment is the encoding and decoding of auxiliary data or state data
> passed through algorithms provided by the library. E.g.
> #define ADD(x, y) WHILE(PRED, OP, (x, y))
> #define PRED(d, state) \
> TUPLE_ELEM(2, 1, state) \
> /**/
> #define OP(d, state) \
> (INC(TUPLE_ELEM(2, 0, state)), DEC(TUPLE_ELEM(2, 1, state))) \
> /**/
> This one type of scenario decreases the efficiency and drastically
> decreases the readability of the code because the TUPLE_ELEM (or similar)
> clutter required in the implementation of both PRED and OP is either
> pervasive or results in more macro definitions.
> Ground-up support would imply that WHILE (and every other higher-order
> macro in the library) allow variadic state such that the example becomes:
> #define ADD(x, y) WHILE(PRED, OP, x, y)
> #define PRED(d, x, y) y
> #define OP(d, x, y) INC(x), DEC(y)
> The amount of clutter, even in this trivial example, is significantly
> reduced resulting in smaller, more efficient, and more readable code.
> However, even doing this requires breaking interfaces because existing
> arguments are in the wrong orders in many places. For example,
> SEQ_FOLD_LEFT's interface is SEQ_FOLD_LEFT(op, state, seq) where op's
> interface must be op(s, state, elem). This would need to be SEQ_FOLD_LEFT
> (op, (a1, a2, ...)(b1, b2, ...), s1, s2, ...) where op's interface must
> "compatible" with op(s, e1, e2, ..., s1, s2, ...). In this case, that's
> variadic accumulation state (i.e. fold state) together with potentially n-
> ary sequence data (in this case, not variadic sequence data such as (1)
> (1, 2)(1, 2, 3), but sequence data that is unary (1)(1)(1), binary (1, 2)
> (1, 2)(1, 2), or whatever so long as each element has the same "arity").

Yes, I remember we discussed this before when we first discussed the VMD
library. As a user of Boost.Preprocessor, I agree 100% that spending the
variadic argument on "data", "state", etc will incredibly simplify my pp
code. However, even without that, variadic support similar to the one added
by VMD is very useful. Therefore, I am looking forward to the
Boost.Preprocessor variadic changes you have made (even if they don't
provide "ground-up" variadic support and I'll have to continue to use
PP_TUPLE_ELEM in the algorithms everywhere).

> All of that aside, there is no way to generalize recursion on broken
> compilers--particularly popular ones such as VC++. The lack of this
> leads to an implementation explosion. Every reentrant algorithm in
> Boost.Preprocessor is implemented with a huge set of macros. Often
> times, they are implemented with multiple huge sets of macros which are
> different in that they contain differing workarounds for various
> compilers. Furthermore, many other higher-order algorithms are not
> reentrant because they are not implemented that way (and are instead
> implemented in terms of the ones which are). This inherently leads to
> implementation bubbling which is particularly costly with the
> preprocessor since there is no direct recursion and because the resulting
> error messages can be as bad as template-related error messages.
> With decent preprocessors, on the other hand, recursion is both
> generalizable and extensible. For example, all higher-order algorithms
> in Chaos are reentrant and none of them are implemented via huge sets of
> algorithm-specific macros. At the end of the day, the lack of
> generalizable recursion is even more fundamental and cripples
> Boost.Preprocessor even more than lack of ground-up support for variadic
> macros. I consider the entire methodology of Boost.Preprocessor to be
> garbage due to widespread, aspectual workarounds. Because of the above,
> I have no incentive to put major effort into minor improvements
> particularly when some vendor is too lazy to fix their preprocessor
> (which is a minor implementation in comparison to the underlying compiler
> and optimizer) or has too much of a "the standard is whatever we say it
> is" mentality.

I understand that MVSC pp is broken and I share the pain of writing endless
workarounds for that pp (especially to ensure proper macro expansions). I
have take a good look look to Boost.Preprocessor implementation and I
understand well the amount of work that went in it to support broken pp...
At the end of the day, I need my code to also compile on MVSC so I'm "stock"
with it whether a I like it or not :(

Thanks a lot!

View this message in context:
Sent from the Boost - Dev mailing list archive at

Boost list run by bdawes at, gregod at, cpdaniel at, john at