Jarrett Billingsley wrote:
Once upon a time, D did not have string mixins, or CTFE, or templates,
or any of the fun things we have today. Even so, it was still
important to be able to access some information about types. So
Walter made it possible to query some basic information - the
initialization value, minimum and maximum allowable values, byte size
and alignment etc. - directly from the types as properties. Neat.
Then D got templates. D's templates were based on C++'s, to an
extent, and therefore made use of specialization (and by corollary,
SFINAE) to determine which template to instantiate. By their nature,
templates are a sort of way of introspecting types. So now D has two
ways to find out things about types. Okay.
It turned out that templates were not always powerful enough - or
sufficiently concise - to express some ideas. So Walter came up with
the is() expression (originally the "iftype" statement which begat
"is()" and "static if") to query other, more interesting information
about types. It's _kind of_ like template specialization but has some
extra features that specialization doesn't. Now D has three ways to
find out things about types. Hm.
Along comes D2, and with it, the __traits keyword. __traits is
wonderful (except for the double-underscore name, anyway). It's
extensible, flexible, and can answer queries about types and other
program objects in a way that would be extremely convoluted or cryptic
if templates or the is() expression were extended.
But now D programs have _four_ ways to ask questions about themselves.
> Some of these methods overlap but with wildly different syntax.
You left out typeof/typeinfo/typeid. There's run-time typeinfo, as well
as compile-time. This is just begging for unification. Consider that in
a CTFE function, you only use run-time syntax, but it's actually
occuring at compile time.
And since Object now contains a factory method, there's considerable
potential for deep unification.