On Wed, Jul 09, 2014 at 07:51:24AM +0200, Philippe Sigaud via Digitalmars-d-learn wrote: > On Tue, Jul 8, 2014 at 7:50 AM, H. S. Teoh via Digitalmars-d-learn > <digitalmars-d-learn@puremagic.com> wrote <quite a wall of text> > > Wow, what to add to that? Maybe you scared other from participating > ;-)
I hope not. :) [...] > * I'd add static introspection to the mix: using static if, > __traits(...) and is(...), clunky as the syntax is (there, one 'ugly' > thing for you), is easy and very powerful: [...] Oh yeah, I forgot about that one. The syntax of is-expressions is very counterintuitive (not to mention noisy), and has too many special-cased meanings that are completely non-obvious for the uninitiated, for example: // Assume T = some type is(T) // is T a valid type? is(T U) // is T a valid type? If so, alias it to U is(T : U) // is T implicitly convertible to U? is(T U : V) // is T implicitly convertible to V? If so, // alias it to U is(T U : V, W) // does T match the type pattern V, for some // template arguments W? If so, alias to U is(T == U) // is T the same type as U? // You thought the above is (somewhat) consistent? Well look at // this one: is(T U : __parameters) // is T the type of a function? If so, alias U // to the parameter tuple of its arguments. That last one is remarkably pathological: it breaks away from the general interpretation of the other cases, where T is matched against the right side of the expression; here, __parameters is a magic keyword that makes the whole thing mean something else completely. Not to mention, what is "returned" in U is something extremely strange; it looks like a "type tuple", but it's actually something more than that. Unlike usual "type tuples", in addition to encoding the list of types of the function's parameters, it also includes the parameter names and attributes... except that you can only get at the parameter names using __traits(name,...). But indexing it like a regular "type tuple" will reduce its elements into mere types, on which __traits(name,...) will fail; you need to take 1-element slices of it in order to preserve the additional information. This strange, inconsistent behaviour only barely begins to make sense once you understand how it's implemented in the compiler. It's the epitome of leaky abstraction. T -- Do not reason with the unreasonable; you lose by definition.