"Andrei Alexandrescu (See Website for Email)"
I'd be the first to agree with that. But isn't it preferrable to have
a good new language to start with and think up from that, instead of
having a poor new language that asks you to do little miracles to get
the most basic things done?
From an immediate productivity standpoint, yes. However, there are a lot of
ways that people think about code (in C++ for example) explicitly because of a
lack of direct language facility. Look at template metaprogramming for example
or SFINAE manipulation. Those things could be implemented better with direct
support from the language, but something beyond that or something completely
different won't be. Because of the kind of thinking that those existing
solutions engender, those other things may not be unreachable. Removing
boilerplate or indirect hacks by adding language features is a neverending
story. Granted, something like recursion is very basic, but then, there are
things that can be done because of the lack of recursion (e.g. I use it to
compare identifiers among other things). As I'm sure that you understand, doing
much with little is also satisfying in its own right. Besides, the "little
miracles" required can be hidden behind a library interface, as Chaos does. I
told you that that was basically doing it by hand. Here's a more high-level
variant:
#define TYPELIST(...) \
CHAOS_PP_EXPR(CHAOS_PP_TUPLE_FOLD_RIGHT( \
TYPELIST_OP, (__VA_ARGS__), Loki::NilType \
)) \
/**/
#define TYPELIST_OP(s, type, ...) \
Loki::Typelist<CHAOS_PP_DECODE(type), __VA_ARGS__> \
/**/
Though there is some, there isn't a lot of boilerplate here. Note also that
this itself is a library interface, and the ultimate boilerplate clutter is all
but gone when user's use the interface. The only relic that you have is that
you have to parenthesize types that contain open commas--which is insignificant.
TYPELIST(int, double, char)
It is also important to note the fundamental thing that is important. This
implementation, along with reusable library abstractions, regardless of
boilerplate, requires only about ten lines of code and completely replaces at
least fifty lines of really ugly repetition (i.e. the TYPELIST_x macros). Note
only does it replace it, but it expands the upper limit from fifty types to
about five thousand types--effectively removing any impact from the limit.
Well if one removes some boilerplate code, C can do virtuals and
templates. That doesn't prove a lot.
No, it doesn't, nor is it meant to. I'm merely pointing out that the
boilerplate is simple when you know what you are doing. It doesn't even get
close to "drowning in details".
I saw only convoluted code in the URL that Dave forwarded.
Which URL was that? If Boost, then the code is drowning in workarounds. If
Chaos, then much of the code you saw is doing much more advanced things than
users need to ever see or do.
I asked for
a good example here on the Usenet. You gave me an example. I commented
on the example saying that it drowns in details. Now you're telling me
that "if you remove the details in which the example is drowning" it
doesn't drown in them anymore. Well ok
).
What I was saying is that the details in that it "drowns in", as you put it, are
nothing but boilerplate. Boilerplate is basically syntactic clutter that you
relatively easily learn to ignore when reading and writing code.
That's reasonable. I just tried to give that as an example. Given that
there *are* things that you cannot do, I was hoping to increase your
(and others') motivation to look into ideas for a new preprocessor.
To be more accurate, there is no code that cannot be generated. It is only a
question of how clean it is and whether it is clean enough to be an acceptable
solution.
As far as a new preprocessor is concerned, I just don't think that it will
happen. I do like the idea of a new kind of macro that can be recursive. That
is the main limitation preventing your imaginary sample syntax. Lack of
backlashes or overloading is insignificant compared to that. Even so, the
ability to process tokens individually, regardless of the type of preprocessing
token, is far more important than any of those, because with that ability you
can make interpreters for any syntax that you like--including advanced
domain-specific languages. (For example, consider a parser generator that
operates directly on grammar productions rather than encoded grammar
productions.) Such an ability would promote C++ to a near intentional
environment.
Regards,
Paul Mensonides