On type functions

Adam D. Ruppe destructionator at gmail.com
Sun May 3 14:14:12 UTC 2020


On Sunday, 3 May 2020 at 09:35:34 UTC, Stefan Koch wrote:
> Avoiding templates unnecessary templates. (i.e.) the maximum 
> number of template-instances creating during this task should 
> be LINEAR to the number of structs printed.

This trivial with D today, you just do the __traits(identifier) 
in a perfectly ordinary function inline.

More interesting might be pulling UDAs off it too. Like if the 
name can be overridden:

string displayName(alias T)() {
       string v = __traits(identifier, T);
       foreach(attr; __traits(getAttributes, T))
          static if(is(typeof(attr) == DisplayName))
                v = attr.name;
       return v;
}

Something like that I do often enough and there is no pretty 
alternative. You can reduce the number of templates by something 
like:

string nameOrDefault(Attrs...)(string def) {
         // loop for DisplayName
}

Which reduces the instantiation to one per unique UDA set; at 
least the common case of zero simplifies but it still isn't great.


The static map proposal in the other thread could help us inline 
this but still a bit wordy.



What's interesting to me is that existing displayName thing 
really should be optimizable to this already! It is pretty 
obviously not dependent on any outside state; it is strongly pure 
(could possibly qualify for the pure keyword too), and it has no 
runtime arguments, which means it has no runtime branch either.

Those two facts together means it should be guaranteed to never 
be anything other than resolve to the literal return value when 
executed.

Moreover, since it returns a value as opposed to a type, that 
satisfies your no state in compiler requirement as well.


So I'd argue that existing template IS a type function and ought 
to be trivially recognized as such by the compiler from its 
existing signature and optimized accordingly - no generation of 
code, no permanent node generated in the compiler, etc. It gets 
even easier to recognize if annotated explicitly with `pure` and 
`assert(__ctfe);` but these are not strictly necessary. The only 
operation technically allowed now on that which would be illegal 
would be &(displayName!(args))... and if that happens maybe it 
could generate it but otherwise it just doesn't.


More information about the Digitalmars-d mailing list