Uniform syntax for templates (second try)

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Oct 12 06:35:44 PDT 2008


Marcin Kuszczak wrote:
> Andrei Alexandrescu wrote:
>> formattedRead("%s", &(int n));
>>
>> The sequence "int n" will be ambiguous with a sequence of types.
> 
> What is this proposal about? Is there some topic on NG? Is above example
> compile time feature? or runtime? 

It's just that you can introduce a symbolic definition whenever an 
expression is expected. So "int n" is good as an expression of type int.

>> d) Let's try another example.
>>
>> void parse(T E : E[], U : bool, V E N : E[N] if(N>100))
>>      (T array, U flag, V sarray);
>>
>> In D2:
>>
>> void parse(E, U : bool, V : E[N], uint N)
>>      (E[] array, U flag, V sarray)
>>      if(N>100);
>>
> 
> It's not the same. In my version you restrict first template parameter to be
> an array, in your example it can be any type. And additionally, isn't
> declaration of N after its usage ugly ;-)

It is the same. Look at how E is used.

>> f) You mention this is not possible, but they are:
>>
>> void do(T : class)(T instance);
>> ===>
>> void do(T : Object)(T instance);
> 
> This will not work for other categories than class and should be considered
> rather as workaround of problem - not solution. Try to make the same with
> struct, union, typedef etc. etc.

I can by saying:

void do(T)(T instance) if (is(T == whatever));

>> void do(T E : E[class])(T sarray, E element);
>> ===>
>> void do(K, V)(V[K] sarray, K element) if (is(K : Object))
> 
> Not an equivalent. You allows here any types. In my version you allow only
> associative arrays with classes as key. My function will not be used for
> template function resolution. Comment for previous case also applies. And
> my syntax is shorter...

The D2 variant is the same because it restricts K to be a class. Also D2 
  eliminates the function from the overload set if the "if" clause is 
not respected (it's pretty much the whole point of the feature).

>> S toupper(isSomeString!(S))(S input)
>> ===>
>> S toupper(S)(S input) if (isSomeString!(S))
> 
> See my comment to your "e"

Equivalent.

>> static if (T : Storage!(STORAGETYPE) if (T == MyType))
>> ===>
>> static if (is(MyType : Storage!(STORAGETYPE), STORAGETYPE)
> 
> You will get syntax error in your example :-).

I know. That's a bug in the compiler.

> It could be avoided with less
> parenthesises. STORAGETYPE is not introduced parameter. Well my example is
> also not very good. Although it would work for following case:
> alias int STORAGETYPE;
> 
> class MyType : Storage!(STORAGETYPE) {
> }
> 
> static if (T : Storage!(STORAGETYPE) if (T == MyType))
> 
> 
>> static if(T == invariant)
>> ===>
>> static if(T == invariant) ----- should be added
> 
> You will probably just get:
> static if(is(T == invariant))

Correct.

> I reserved already version without is() :-)
>  
>> static assert(V E K : E[K] if (K == int), "Not supported");
>> ===>
>> static assert(is(V : E[int], E), "Not supported");
> 
> Please notice that my syntax doesn't disallow shorter version:
> static assert(V E : E[int], "Not supported");
> 
> In such a case it is even shorter.
> 
>> g) I think this is a rather minor improvement:
>>
>> alias Variant[][] A B C;
> 
> I agree. Probably it should be just a syntax error.
> 
>  
>> h) I think this should be supported one way or another. Decomposing
>> types quickly and easily would be a boon.
>>
>> alias T U : U[];
>> alias T U N : U[N=uint] if (N>100);
> 
> Yep. It's usefull in some cases. But why not to do it in same way as other
> compile time constructs and introduce something new?
> 
> ---
> 
> As general comment I would like to notice that I am not considering this
> syntax as finished work. There might be some changes in it, and I even
> don't care too much about all details which should be adjusted. In my
> opinion major advantages of this proposal are:
> 
> 1. Same syntax for practically every compile time expression in D. You have
> to learn it only once and then intuitively you will apply same pattern in
> every case. Currently you have to learn by heart the whole IsExpression
> table and additionally syntax for template functions. E.g. matching static
> arrays, is far from intuitive, and even I would say that it is against good
> practices of programming which demands that symbols are defined *before*
> usage, not after.

Uniformity is good.

> 2. Dropping redundant IsExpression for templates. This makes a lot of code
> easier to read (e.g. because of less parenthesis). The notation gets also
> shorter.

I think this is rather minor.

> 3. My proposal is more flexible & extensible than current syntax(-es). It's
> also shorter in general case. And adding additional possibilities to this
> compile time expression will allow to use them in all compile time
> statements, differently than it is now.

I'm not sure about terseness. Your patterns tend to introduce more symbols.

> 4. It seems additionally that better pattern matching will render redundant
> many use cases for if(ct_expression).

Yah, that I'm looking forward to.

This is a big change. To sell this big change to people and Walter, you 
need to have some smashing advantages. So far you have I'm not seeing a 
smashing advantage. Easily decomposing types in patterns would be one, 
but that is something that could be pulled out of your proposal and 
implemented alone.


Andrei



More information about the Digitalmars-d mailing list