Simplifying templates

Bill Baxter wbaxter at gmail.com
Sat Nov 29 14:14:36 PST 2008


On Sun, Nov 30, 2008 at 6:05 AM, dfgh <dfgh at mailinator.com> wrote:
> Warning: this would break existing code.
>
> I have an idea for a completely new template syntax that is easier to use and implement. I'll explain it in therms of a hypothetical language called Dscript. Let's start by imagining that Dscript works identically to D 2.0, but it is interpreted and dynamically typed, with eval's (this is not intended to be implemented, and not the main point of this post). Obviously there isn't much of a point to creating two languages with the same syntax, especially since Dscript would be useless for systems programming, contradicting one of the design goals of D. However, there are some things that you can't do if you have static type enforcement. For example, in D this is impossible:
>
> template foo(string Type) {
>    invariant foo = eval(Type ~ ".init");
> }

Actually something similar is possible in current D with string
mixins.  But they have to be full statements and not expressions.

template foo(string Type) {
   mixin("invariant foo = "~Type~".init;");
}

But it might be nice if string mixins worked for expressions too.  I
presume there's some reason Walter didn't make them work as
expressions, though.

> Well, I have only been using it to convert strings into types, so what if we made a type type?
> type myint = int;                                    //we don't need alias anymore
> type myOtherInt : int;                             //or typedef, note the colon
> type[3] threeIntegers = [short, int, long]; //and tuples are now built-ins
>
> // ! syntax is obsolete too, because templates are functions
> to(myint, 13.7);
>
> //and is-expressions are simpler
> if(int <= float) {
>    writeln("int is cast-able or identical to float.");
> }

For this, what you say might be easier for the user (i'm not convinced
though, because now when I see if(a<b) I first have to figure out if
that's types or values).   But some of those are definitely harder for
the poor compiler, who has to decide if the stuff inside the if() is
working on types or values.  So it will have to delay creating the
final syntax tree until the semantic pass.  Walter won't like this.

Also types aren't necessarily an ordered relation in the way that
int<=float implies.  It could be that both A is implicitly convertible
to B and B is implicitly convertible to A, but A!=B.  I think that's
why is() expressions use the colon for that now rather than the <.

> if(myint == int) {
>    writeln("myint and int are the same type.");
> }
>
> import std.socket;
>
> if(UdpSocket <: Socket) {
>    writeln("UdpSocket extends Socket.");
> }
>
> Everything is so much simpler!

How do you replace the versions of 'is' that infer a type and make an
alias to it?
like if(is(T S : T[])   (or whatever that horrible syntax is.)

> This is easier for both programmers and compilers, but we still have one problem: dynamic typing. This isn't too hard to eliminate, though; we just have to make sure that whenever we use a type, it's known at compile time. This checking is already in place, for example integer template parameters are known at compile-time. If necessary, it can also be easily accomplished by making types immutable. What about templates with non-type parameters, such int's? Simple:
>
> int bar(string str, static int abc, type T)

This one looks like the proposal Walter and Andrei discussed at the D
2007 conference.  The static int part anyway.  I'm not sure they were
planning to allow passing types that way or not.

> We've created a language just like D, except it simplifies alias's, typedef's, tuples, is expressions, and especially templates, all the confusing and hard-to-learn aspects. Instead, we have the much more elegant syntax of types.

I kind of like the idea of unifying syntax for manipulating types and
values, but it has to be done in such a way that the compiler can
still easily parse the result without having to do the semantic
analysis to figure out if the expression is about types or not.   For
instance a while back I was suggesting we use '=' with alias:  "alias
FloatAlias = float"  so that type assignment looks more like value
assignment.

--bb



More information about the Digitalmars-d mailing list