Boost logo

Boost :

Subject: Re: [boost] [Preprocessor] Adding variadic macros support
From: Edward Diener (eldiener_at_[hidden])
Date: 2010-11-27 11:57:41


On 11/27/2010 9:36 AM, Paul Mensonides wrote:
> On Thu, 25 Nov 2010 08:42:37 -0500, Edward Diener wrote:
>
>> You are right. Evidently the code is under CVS, but not under SVN ( yet
>> ? ).
>>
>> I will look at Chaos and see what is done.
>
> You'll have to pull it out of the CVS repository. The Subversion
> respository is not being used yet. The library is complete, as of right
> now there are more than five hundred primary interface macros (i.e. not
> counting implementation macros). There are more than two thousand
> interface macros if derivative macros are included (still not including
> implementation macros).
>
> If you checkout from the CVS, there is a file $CHAOS_ROOT/built-docs/
> headers.html that lists all of the headers in the library. The first
> link (i.e.<chaos/preprocessor.h>) might be more useful for navigation.
> The reference documentation is complete (and extensive) except for a
> couple of macros that I added recently. There are lots of examples
> (mostly contrived). The topical documention is not complete, but feel
> free to ask me whatever you want.

I actually just downloaded the tar.gz file. While I could get Tortoise
CVS and use it to keep up to date, I have gotten lazy enough where since
its not in SVN ( or Git ) I tend not to want to have to deal with CVS
anymore. But that's my problem.

>
> Chaos' use of variadics is controlled by CHAOS_PP_VARIADICS. This is
> normally set automatically based on whether the language supports
> variadics. However, there is currently no usable definition of
> __cplusplus for it to work with. Thus, by default, variadics are
> disabled in C++. However, the macro CHAOS_PP_VARIADICS can be defined on
> the command line to override the automatic settings. E.g. with GCC...
>
> g++ -E -P -std=c++0x -I $CHAOS_ROOT -D CHAOS_PP_VARIADICS test.cpp

Perfectly reasonable.

>
> ===== Requirement for a Compliant Preprocessor =====
>
> The techniques used by Chaos' internals are *extremely* advanced. Most
> of the time, they require the preprocessor to do *exactly* what it should
> do according to the standard(s). Because of that, Chaos cannot be ported
> to broken preprocessors like MS (and putting workarounds in the source
> would defeat the purpose of Chaos even if such workarounds were possible).
>
> I believe that GCC, EDG-based compilers, and Wave are 100% usable. There
> are a few others that are mostly usable as well as a few tools that have
> internal (custom) preprocessor implementations that are 100% usable
> also. In particular, VC++ is *not* usable. I am not sure about Sun at
> the moment.

What are the chances that you would be willing to propose Chaos for
Boost even though it would work with only a subset of compilers, and
specifically not with VC++ ? I personally think this would still be
valuable for the authors of Boost libraries and for end-users, but I
could understand your unwillingness to do so or other Boost developers
and/or end-users unwillingness to accept Chaos into Boost because it
does not work for a number of C++ compilers. But IMO that Chaos would
provide easier preprocessing programming for even a subset of C++
implementations would make it worth using.

>
> ===== Notable Differences from the Boost pp-lib =====
>
> The most obvious (considering the context) is support for variadics/
> placemarkers from the ground up. Probably more importantly, Chaos
> generalizes recursion and all higher-order constructs are reentrant
> without replication of their implementations.

That is an excellent advantage in simplification over current Boost PP
despite the fact that you have made Boost PP quite usable even with the
recursion difficulties.

> As an example, take a look
> at the implementation of BOOST_PP_REPEAT compared to the following:
>
> #define REPEAT(n, macro, ...) \
> REPEAT_S(CHAOS_PP_STATE(), n, macro, __VA_ARGS__) \
> /**/
> #define REPEAT_S(s, n, macro, ...) \
> CHAOS_PP_IF(n)( \
> REPEAT_I, CHAOS_PP_EAT \
> )( \
> CHAOS_PP_OBSTRUCT(), CHAOS_PP_NEXT(s), \
> CHAOS_PP_DEC(n), macro, __VA_ARGS__ \
> ) \
> /**/
> #define REPEAT_INDIRECT() REPEAT_S
> #define REPEAT_I(_, s, n, macro, ...) \
> CHAOS_PP_EXPR_S _(s)(REPEAT_INDIRECT _()( \
> s, n, macro, __VA_ARGS__ \
> )) \
> CHAOS_PP_CALL(macro)()(s, macro, n, __VA_ARGS__) \
> /**/
>
> #define MACRO(s, n, ...) \
> CHAOS_PP_COMMA_IF(n) class T ## n \
> /**/
>
> CHAOS_PP_EXPR(REPEAT(
> 5, MACRO, ?
> ))
>
> ===== Variadics as Data Structures =====
>
> Over the course of development of Chaos, I rapidly discovered that the
> direct use of variadics as element sequences is only marginally useful
> (at best). Variadics are better used for other things. Let me clarify.
> Variadics as raw data structures are virulent. They take over the
> interface of everything else by forcing particular argument orders and
> "stealing" the single variadic "argument". As an obvious example, you
> can't have an algorithm that operates on two such data structures.
>
> OTOH, variadics used indirectly in data structures are very useful (e.g.
> variadics sequences). Even with tuples such that the size is not
> required to be known for element access. Long story short, (...) is
> better than just ... for all kinds of reasons.

I totally agree and made a point of saying in my variadic_macro_data
library that variadic macros real advantage over Boost PP sequences is
largely in familiarity/ease of syntax for end-users. I am glad you have
also found their usage in data structures valuable.

>
> ===== Lambdas/Binding =====
>
> Chaos has a pretty heavyweight lambda engine. For example (contrived),
>
> #include<chaos/preprocessor.h>
>
> CHAOS_PP_EXPR(CHAOS_PP_ENUM(
> 5,
> CHAOS_PP_PRIMITIVE_CAT_(class T, CHAOS_PP_ARG(1))
> CHAOS_PP_WHEN_(CHAOS_PP_ARG(1))(
> CHAOS_PP_CAT_(= T, CHAOS_PP_DEC_(CHAOS_PP_ARG(1)))
> )
> ))
>
> ...results in:
>
> class T0, class T1 = T0, class T2 = T1, class T3 = T2, class T4 = T3
>
> However, the problem with lambdas (with the preprocessor) is that they
> are considerably more expensive. No matter how you do it, it requires
> some sort of interpretation--which is slower--and simply having a macro
> is usually clearer. I've actually been considering their removal from
> Chaos for several years.
>
> #define _(s, n) \
> class T ## n \
> CHAOS_PP_WHEN(n)(= CHAOS_PP_CAT(T, CHAOS_PP_DEC(n))) \
> /**/
>
> CHAOS_PP_EXPR(CHAOS_PP_ENUM(5, _))
>
> #undef _

If lambdas are syntactically easier to use I would still encourage you
to keep them in Chaos. While I am never against techniques which
increase compile-time speed I strongly feel that ease of use in
programming is far more important than waiting longer for a compilation
to finish.

Thanks very much for explaining more about Chaos.


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