Uniform syntax for templates (second try)

Marcin Kuszczak aarti_please_no at spam_interia.pl
Sun Oct 12 04:00:27 PDT 2008


Andrei Alexandrescu wrote:

> Marcin Kuszczak wrote:
>> This is my second try to propose better syntax for templates. My previous
>> proposal was added to bugzilla:
>> http://d.puremagic.com/issues/show_bug.cgi?id=1827
>> 
>> In this proposal I modified a little bit syntax, took into consideration
>> more cases and put into table few examples of new syntax compared to old
>> one.
>> 
>> Attached html version of document. Other formats are too big to send it
>> through news group, but they are available on request.
>> 
>> I hope for comments from you :-)
> 
> I'll make some candid comments without speaking for Walter.

First of all thanks for your comments. I really appreciate them.
My comments are inlined below.

 
> a) The proposal prevents creating names in expressions, something we
> were talking about:
> 
> 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? 

Well it was difficult for me to take it into consideration, because I was
unaware of this proposal... :-)

> b) At point 4 my eyes started glazing a bit.
> 
> void changeElement(T U N : U[N=uint] if(N>100))
>      (T array, U value, int index);
> 
> The N=uint jumps as a surprising baroque element. 

Another alternative would be e.g.:
void changeElement(T U N=uint : U[N] if(N>100)) (T array, U value, int
index);
Above was in my first proposal (in bugzilla). Then default value could be
given as N=uint(5) where necessary.

or 

void changeElement(T U uint N : U[N] if(N>100)) (T array, U value, int
index);

What ever syntax would be choosen, it should be also choosen for default
template parameters.

Maybe some other syntax for default parameter type/value should be invented.
I don't care so much about that until the main advantages (summarized at
the end of this post) will be kept...

> Besides, U[N=uint] 
> could be interpreted as a hash with uint as the default key type.

No, because you are "fixing" one dimension (type) of type variable, and are
still expecting N to be defined by compiler. On compile time it is only
possible for static array, where N (value) is known at compile time. For
associative arrays it would be an error.

Side note: In fact it seems that arrays can be treated as special case of
associative arrays with perfect hashes, so your notice is fully
understandable ;-)

 
> The rewrite in current D2 is:
> 
> void changeElement(T : U[N], U, uint N)
>      (T array, U value, int index)
>      if (N > 100);
> 
> To me it's not clear which is better. The second actually may be more
> expressive because you can collectively use all elements of the template
> in one place, something much clunkier in the other version.

Yes, you are right. And after rethinking this case I think that current if()
after function arguments can stay as it is with global access to all
defined symbols. But in my opinion it should be added also as (optional)
extension for pattern matching expression. This way it will be possible to
use such expression in every compile time statement.
 
> c) I totally agree that this should be abolished:
> 
> string stringize(T : T[])(T value);

Yeah. I know :-)

 
> 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 ;-)


> e) This will be very hard to understand for both human and machine:
> 
> S toupper(isSomeString!(S))(S input)

Please don't consider this example and my comments below as part of my main
proposal. This example is more about template specialization resolution,
not about syntax of compile time expression. I didn't put much thinking in
template specialization resolution so below only few random thoughts:

It might be possible to define score based template function resolution. For
every function some logic in compiler would calculate points for "is
function matching". In case one of parameters don't match score would be 0
(false). In other cases there should be chosen function with maximal score. 

Well, I will stop now, as ground is getting more and more swampy :-)


> 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.

> 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...

> S toupper(isSomeString!(S))(S input)
> ===>
> S toupper(S)(S input) if (isSomeString!(S))

See my comment to your "e"
 
> static if (T : Storage!(STORAGETYPE) if (T == MyType))
> ===>
> static if (is(MyType : Storage!(STORAGETYPE), STORAGETYPE)

You will get syntax error in your example :-). 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))

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.

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.

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.

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


-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------




More information about the Digitalmars-d mailing list