Russ Lewis wrote: "Walter (and everybody else), I was looking for your opinion on how mixins are different than macros. Haven't we just recreated the old moster in a new guise?"
It's an excellent question. Mixins are the same (and different from) templates just like C++ templates are the same and different from macros.
Some of the differences are:
- Mixins substitute in parsed declaration trees that pass muster with the language syntax, macros substitute in arbitrary preprocessor tokens that have no organization.
- Mixins are in the same language. Macros are a separate and distinct language layered on top of C++, with its own expression rules, its own types, its distinct symbol table, its own scoping rules, etc.
- Mixins are selected based on partial specialization rules, macros have no overloading.
- Mixins create a scope, macros do not.
- Mixins are compatible with syntax parsing tools, macros are not.
- Mixin semantic information and symbol tables are passed through to the debugger, macros are lost in translation.
- Mixins have override conflict resolution rules, macros just collide.
- Mixins automatically create unique identifiers as required using a standard algorithm, macros have to do it manually with kludgy token pasting.
- Mixin value arguments with side effects are evaluated once, macro value arguments get evaluated each time they are used in the expansion (leading to weird bugs).
- Mixin argument replacements don't need to be 'protected' with parentheses to avoid operator precedence regrouping.
- Mixins can be typed as normal D code of arbitrary length, multiline macros have to be backslash line-spliced, can't use // to end of line comments, etc.
- Mixins can define other mixins. Macros cannot create other macros.