Variants and pattern matching implementation

Reiner Pope reiner at none.com
Sun May 13 00:07:37 PDT 2007


David B. Held wrote:
> Reiner Pope wrote:
>> [...]
>> 2. Lack of types for templates parameters.
>> It would really be nice to express what *kind* of template parameters 
>> you want in more detail (this specifically refers to alias parameters, 
>> and their tuple counterparts). I know of at least three specific times 
>> in writing the variant that I forgot/misunderstood the type the 
>> parameter was -- I can't help feeling that some kind of Concepts idea 
>> for template parameters would be nice.
>> [...]
> 
> This is my favorite hobby-horse, so if you could elaborate on this with 
> some specific examples, that would be great. ;)
> 
> Dave

Take some of the code currently in variant.d:

> template GenerateCases(VType, bool Strict, IndicesThenCases...)
> {
>     ...
>     const ulong[] indices = TypeIndices!(TheType, VType.Types);
>     ...
> }


1. A varargs template parameter is the only way to pass around a ulong[] 
as a template parameter; you can't write
          template Foo(ulong[] T1) {...}

    That is why the IndicesThenCases parameter is so named, since it's 
actually two parameters.

2. The tail of IndicesThenCases is (obviously enough) a list of cases. 
It makes sense if you think about it, but the following line from above:

>          const ulong[] indices = TypeIndices!(TheType, VType.Types);

used to actually be

>         const ulong[] indices = TypeIndices!(VType, Cases);

When I came to that bug, the compiler printed several pages of template 
instantiations. What was worse was that the ulong[] there caused them to 
be displayed mangled, not as plain text. It was mostly guesswork to find 
that as the bug, since the compiler didn't give any useful information.

Of course, if Cases had been typed as a list of template instantiations, 
and TypeIndices had stated it required a list of types, it would have 
been a simple type mismatch, and easier to find.

3. Another problem is the form of the Match!() template, because it 
expects a list of Cases. The code pattern I use to check the user is 
providing this is the following idea:

> template CaseImpl(...)
> {
>     const bool IsCase = true;
>     ....
> }
> 

and later (although I forgot this in the code I released):

> static assert(is(typeof(Cases[0])), "The match statement expects a list of Cases");

Which seems a bit silly when you consider I am just ensuring the 
template parameters are the right type.



That's all that comes to mind now. Are there any thoughts about 
implementing some kind of concepts/checking for template parameters? I'm 
especially uncertain of nested tuples and value parameters, which both 
currently (and a lot more) are all hidden behind the single

> template Foo(T...)

idiom.


Cheers,

Reiner



More information about the Digitalmars-d mailing list