Get template and its instantiation parameters

Michal Minich michal.minich at gmail.com
Wed Oct 7 14:16:17 PDT 2009


On Wed, 07 Oct 2009 13:15:46 -0400, Jarrett Billingsley wrote:

> On Wed, Oct 7, 2009 at 12:54 PM, BCS <none at anon.com> wrote:
>> Hello Michal,
>>
>>> If one has a template instance, is it possible to get template name
>>> and parameter type that was used for instantiating, at compile time?
>>>
>>> consider:
>>>
>>> class List (T) {}
>>>
>>> List!(int) lst;
>>> Foo (lst);
>>> I want to create such template Foo which prints: List!(int)
>>> List
>>> int
>>
>> You could try parsing T.stringof at compiletime to extract the parts
>> you need.
> 
> This is *exactly* the kind of bullshit that I hate about string mixins.
> The thought process just ends up going "oh, why bother having any terse,
> elegant mechanisms to get at program information when you can *parse
> arbitrary code at compile time*? And why do you need macros when a
> string substitution will do?" Is it powerful? Sure. But it's lame, ugly,
> slow, easy to mess up, lacks hygiene, and is unidiomatic. String mixins
> are basically just a text preprocessor with user-defined functionality.
> Neat, but it can only get you so far before you're in tarpit territory.

Jarrett,

I agree with you except the "lame" and "preprocessor" part. But I 
wouldn't be so harsh on D. The prospect of parsing D code really does not 
appeal to me. Also the usage of advanced templates is not very intuitive. 
But please don't forget that features that are made possible by D 
templates and/or the ".stringof" + CTFE are not available in many 
languages. Languages that have such or better type level expressivity as 
D are few, mostly functional ones: Haskell, ML, OCaml, F# (I don't know 
of Scala). Also these features in D are more general, and even if kludgy, 
they are *available*.


The answer to my question is:

The problem was that parameter T needs to be "alias" because it should 
match "List" which is not complete type, until is applied to some 
argument (int); it is just template name. The result for T.stringof is 
surprising for me, but anyway, I get what I needed.

class List (T) {}

void main ()
{
    List!(int) lst;
    Foo (lst);
}


template Foo (C : T!(U), alias T, U)
{
    void Foo (C container)
    {
        writeln(C.stringof); // List
        writeln(T.stringof); // List(T)
        writeln(U.stringof); // int
    }
}

(tested on DMD 2.033)


More information about the Digitalmars-d-learn mailing list