
On Sun, 22 Apr 2012 00:09:52 -0700, paul Fultz wrote:
I understand that Chaos won't implement workarounds. I was thinking more of forking chaos, and trying to implement it in msvc. Would that be a possibility? And with your knowledge of Chaos's implementation and msvc limitations, do you even think that it would even be remotely feasible?
I don't think it's feasible. You *might* be able to emulate the base interface over a completely separate (and much larger) implementation. However, you won't be able to emulate the extensibility model. For example, one of the defining things about Chaos is its ability to generalize recursion (not referring to the sequence tricks that I started this thread with). That generalization of recursion reaches into client code. This model is quite different from (e.g.) the Boost pp-lib where you have end-user -> boost-pp This end-user might be a library, of course, and there may be a few exceptions, but not really. The pp-lib itself is incapable of reusing itself properly--how many times have there been complaints that algorithm XYZ is not reentrant? Essentially, the boost-pp model is just not extensible. In Chaos, however, you have a model that is more like regular software: end-user -> { chaos-pp 3rd-party-library } 3rd-party-library -> { chaos-pp 3rd-party-library } The closest reference to the core language that either boost-pp or chaos- pp makes is probably ENUM_PARAMS. However, there is a huge "unexplored" area between the relatively low-level preprocessor libraries like boost-pp and chaos-pp and the higher level semantics of the core language with scenarios that are more specific than the low-level libraries but still library-izable (!!). For example, any powerset contains the nil set. However, one doesn't always want it in the result. So, I might do: #define A(s, seq) \ CHAOS_PP_INLINE_WHEN(CHAOS_PP_SEQ_IS_CONS(seq))( \ /* DO WHATEVER */ \ ) \ /**/ CHAOS_PP_EXPR(CHAOS_PP_SEQ_FOR_EACH( A, POWERSET(SEQ) )) However, even though /* DO WHATEVER */ may not be generalizable, the predication is. So, I might instead do something like: #define FILTER(s, e, p, ...) \ FILTER_I( \ CHAOS_PP_OBSTRUCT(), CHAOS_PP_NEXT(s), e, p, \ CHAOS_PP_NON_OPTIONAL(__VA_ARGS__), \ CHAOS_PP_PACK_OPTIONAL(__VA_ARGS__) \ ) \ /**/ #define FILTER_I(_, s, e, p, m, pack) \ CHAOS_PP_INLINE_WHEN _( \ CHAOS_PP_CALL(p)()(s, p, e CHAOS_PP_EXPOSE(pack)) \ )( \ CHAOS_PP_CALL(m)()(s, m, e CHAOS_PP_EXPOSE(pack)) \ ) \ /**/ #define A(s, seq) /* DO WHATEVER */ CHAOS_PP_EXPR(CHAOS_PP_SEQ_FOR_EACH( FILTER, POWERSET(SEQ), CHAOS_PP_SEQ_IS_CONS_(CHAOS_PP_ARG(1)), A )) This isn't perfect--it doesn't deal with non-unary sequences, for example. However, that could be accomplished with similar sorts of chaining. Now, in the above, SEQ_FOR_EACH is reentrant, the predicate called by FILTER can use FILTER, and thus FILTER is reentrant. The macro, A can be made reentrant (if necessary). And all these reentrancies are bouncing around between potentially multiple libraries and user code (let's say CHAOS_PP_* is provided by Chaos (C), FILTER is provided by library A, POWERSET is provided by library B (which somehow uses library A), and the end-user (E) does the above). This works because of the extensibility of the architecture. Emulating the interface is one thing--which still might not be possible with MSVC. Emulating the extensibly with MSVC, in particular, is either impossible or difficult beyond belief. Regards, Paul Mensonides