www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Simplifying templates

reply dfgh <dfgh mailinator.com> writes:
Bill Baxter Wrote:

 On Sun, Nov 30, 2008 at 6:05 AM, dfgh <dfgh 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.

You're right, I forgot about that feature.
 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).

Types are either primitives or capitalized, assuming capitalization convention is followed.
 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.

It no more complex than normal operator overloading, which is supported.
 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 <.
 

Good point, we need better syntax than my proposal. We could make new operators if necessary. Maybe cast-able and implicitly convertible should each have their own syntax. We could stick with is-expressions and still retain the main part of my idea, but I don't like them. Their rules are too different from the syntax of the rest of the language, so they must be learned separately.
 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.

I forgot that this existed. Anyway, by passing type's with the same syntax as variables we completely eliminate the function/template dichotomy, simplifying the language.
 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

To conclude (again), C is based around functions and struct's, Lisp is based around cons's and atoms, Java is based around classes, and Smalltalk is based on messages and classes. Many similar features in D are currently written very differently, preventing it from having the unified feel that these other languages enjoy, and most of the minor, confusing features are caused by an inability to talk about types using the same concepts as data. --Sam
Nov 29 2008
parent reply Michel Fortin <michel.fortin michelf.com> writes:
Interesting. Have you seen the thread I started last Tuesday suggesting 
mostly the same thing: treating types like values? I ended up with what 
looks like a solution to get rid of most uses for templates (replacing 
them with compile-time-only functions returning types).

Look for 'The "type" type dream', starting here:
<http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=80077>

-- 


Michel Fortin
michel.fortin michelf.com
http://michelf.com/
Nov 29 2008
parent reply dfgh <dfgh mailinator.com> writes:
Michel Fortin Wrote:

 Interesting. Have you seen the thread I started last Tuesday suggesting 
 mostly the same thing: treating types like values? I ended up with what 
 looks like a solution to get rid of most uses for templates (replacing 
 them with compile-time-only functions returning types).
 
 Look for 'The "type" type dream', starting here:
 <http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=80077>
 
 -- 
 
 
 Michel Fortin
 michel.fortin michelf.com
 http://michelf.com/
 

That is very similar to my idea, except it would allow dynamic typing. We do have dynamic typing to some extent in D (Variant's, variadic functions), but it slows down code. I prefer enforcing static typing, especially given D's design goals, such as systems programming. Code that needs dynamic typing is the exception, so it gets Variant's rather than a part of the core language. --Sam
Nov 30 2008
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2008-11-30 11:00:07 -0500, dfgh <dfgh mailinator.com> said:

 That is very similar to my idea, except it would allow dynamic typing. 
 We do have dynamic typing to some extent in D (Variant's, variadic 
 functions), but it slows down code. I prefer enforcing static typing, 
 especially given D's design goals, such as systems programming. Code 
 that needs dynamic typing is the exception, so it gets Variant's rather 
 than a part of the core language.

Yes and no. My idea was that such functions would only work at compile time (like current CTFE). When mixed with other parameters the part about the types would need to work at compile time, it would create a new function instance for each type argument you give it in the arguments. Basically, it'd behave mostly as current function templates. It has been proposed in that thread that this be extended to dynamic typing, which I agree could be done using the same syntax. But dynamic typing is out of my proposal. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 01 2008