On Monday, 1 June 2015 at 18:44:02 UTC, Atila Neves wrote:
1. Backwards compatibility with existing C++ code
2. Being able to call C code that depends on macro definitons
to actually work
3. The aforementioned cases in which templates can't do the job
With regards to #3: see when you use `mixin` in D code? You
need a macro to achieve the equivalent task in C++. It's either
that or boilerplate. Yay when I get to write D, boo when I just
have to use C++. I feel dirty every time I type `#define`, but
I'd feel dirtier if I repeated code all over the place. As
always, it's a trade-off.
Yes, it is a trade-off. 20 years ago I tried to write terser code
and do code gen with macros if possible, now I don't mind some
repeated code as it is often easier to understand later on than
indirections and I often find that building tables etc with an
external tool is cleaner than macros anyway.
Some boiler plate, like SFINAE templates for testing type
properties ("does the class have a .length() function") look
really ugly in C++ compared to newer languages, but I keep those
tucked away in a header file, so it is not so bad. The good thing
about this is that I don't get tempted to add SFINAE constructs I
don't understand, which is an advantage when debugging...
I agree macros are needed for reasonable C interop, but
_unfortunately_ the presence of macros is like a sleeping pillow
for the C++ language-designers that allows them to add new pieces
without getting down to a clean core language.
As for mixins, I don't like those either. You can often get
around that with analysis that leads to a well thought out
design, but I agree that sometimes it is too late for that and
boilerplate or macros ensue as a result of evolution… The
question then is, would a lack of textual-substitution-first-aid
have made the architect/programmers spend more time on design
before coding?
So yes, providing and using macros is a trade-off, but I usually
of the wrong kind. (E.g. a convenient excuse for not cleaning up
the language or the application design)