www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Implicit instantiation of parameterless templates

reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Java and C# with their generics can do the following:

class List { }
class List<T> { }

List list = new List();
List<int> intList = new List<int>();

In D similar code can't work because we can't have both a type and a 
template with the same name. So this code must be rewritten to:

class List(T = Variant) { }

List!() list = new List!();
List!int intList = new List!int;

When template name is used as a type and it can be instantiated with no 
parameters it could be automatically rewritten to List!() by the 
compiler. That code would then look like this:

List list = new List;
List!int intList = new List!int;

The question is... is it possible to change D's behaviour to avoid 
awkward !() template parameters _without_ breaking backward compatibility?
Oct 05 2012
next sibling parent reply "Paulo Pinto" <pjmlp progtools.org> writes:
On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:
 Java and C# with their generics can do the following:

 class List { }
 class List<T> { }

 List list = new List();
 List<int> intList = new List<int>();

 In D similar code can't work because we can't have both a type 
 and a template with the same name. So this code must be 
 rewritten to:

 class List(T = Variant) { }

 List!() list = new List!();
 List!int intList = new List!int;

 When template name is used as a type and it can be instantiated 
 with no parameters it could be automatically rewritten to 
 List!() by the compiler. That code would then look like this:

 List list = new List;
 List!int intList = new List!int;

 The question is... is it possible to change D's behaviour to 
 avoid awkward !() template parameters _without_ breaking 
 backward compatibility?

Why to you need this? Java and C# only allow this type of code due to backwards compatibility, because their first version did not allow for generics, and their creators did not want to force everyone to recode their code bases. -- Paulo
Oct 05 2012
parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Paulo Pinto wrote:
 On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:
 Java and C# with their generics can do the following:

 class List { }
 class List<T> { }

 List list = new List();
 List<int> intList = new List<int>();

 In D similar code can't work because we can't have both a type and a
 template with the same name. So this code must be rewritten to:

 class List(T = Variant) { }

 List!() list = new List!();
 List!int intList = new List!int;

 When template name is used as a type and it can be instantiated with
 no parameters it could be automatically rewritten to List!() by the
 compiler. That code would then look like this:

 List list = new List;
 List!int intList = new List!int;

 The question is... is it possible to change D's behaviour to avoid
 awkward !() template parameters _without_ breaking backward
 compatibility?

Why to you need this?

For convenience. In the above example, List without parameters could handle any value (as Variant), but I can always specialize it for some type. List (which would be List!()) would then become a shortcut to List!Variant.
 Java and C# only allow this type of code due to backwards compatibility,
 because their first version did not allow for generics, and their
 creators did not want to force everyone to recode their code bases.

Yes, but it's more convenient to write List than List<Object>. And in D: List vs List!().
Oct 05 2012
prev sibling next sibling parent "David Piepgrass" <qwertie256 gmail.com> writes:
On Friday, 5 October 2012 at 12:24:12 UTC, Paulo Pinto wrote:
 On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:
 Java and C# with their generics can do the following:

 class List { }
 class List<T> { }

 List list = new List();
 List<int> intList = new List<int>();

 In D similar code can't work because we can't have both a type 
 and a template with the same name. So this code must be 
 rewritten to:


 Why to you need this?

 Java and C# only allow this type of code due to backwards 
 compatibility, because their first version did not allow for 
 generics, and their creators did not want to force everyone to 
 recode their code bases.

The Java and C# situations are very different. In Java, generics are "erased" at runtime so a List<int> is the same thing as a List. In C#/.NET, however, List<int> and List are 'unrelated' types, which is what Piotr was talking about. .NET allows "overloading" types based on the number of generic parameters, so for example Tuple<X> is a different type than Tuple<X,Y> (the runtime names are Tuple`1 and Tuple`2). Since C# has no "default arguments" for generics or "tuple template parameters", it is trivial to allow different types that have the same name but a different number of generic parameters. In D, however, the situation is a bit more complicated.
Oct 05 2012
prev sibling next sibling parent reply "F i L" <witte2008 gmail.com> writes:
On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:
 Java and C# with their generics can do the following:

 class List { }
 class List<T> { }

 List list = new List();
 List<int> intList = new List<int>();

 In D similar code can't work because we can't have both a type 
 and a template with the same name. So this code must be 
 rewritten to:

 class List(T = Variant) { }

 List!() list = new List!();
 List!int intList = new List!int;

 When template name is used as a type and it can be instantiated 
 with no parameters it could be automatically rewritten to 
 List!() by the compiler. That code would then look like this:

 List list = new List;
 List!int intList = new List!int;

 The question is... is it possible to change D's behaviour to 
 avoid awkward !() template parameters _without_ breaking 
 backward compatibility?

+1 This is natural. Plus, this has other uses I've mentioned on here in the past, "sub-scoping": class Foo { int bar; template baz { int bar; } } void main() { auto f = new Foo(); f.bar = 0; f.baz.bar = 1; } Currently, this syntax is possible, but requires to some ugly work-arounds.
Oct 05 2012
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 05-Oct-12 23:25, F i L wrote:
 On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:
 Java and C# with their generics can do the following:

 class List { }
 class List<T> { }

 List list = new List();
 List<int> intList = new List<int>();

 In D similar code can't work because we can't have both a type and a
 template with the same name. So this code must be rewritten to:

 class List(T = Variant) { }

 List!() list = new List!();
 List!int intList = new List!int;

 When template name is used as a type and it can be instantiated with
 no parameters it could be automatically rewritten to List!() by the
 compiler. That code would then look like this:

 List list = new List;
 List!int intList = new List!int;

 The question is... is it possible to change D's behaviour to avoid
 awkward !() template parameters _without_ breaking backward
 compatibility?

+1 This is natural. Plus, this has other uses I've mentioned on here in the past, "sub-scoping": class Foo { int bar; template baz { int bar; } } void main() { auto f = new Foo(); f.bar = 0; f.baz.bar = 1; } Currently, this syntax is possible, but requires to some ugly work-arounds.

Hm... If placed at the global scope it looks like a namespace. -- Dmitry Olshansky
Oct 05 2012
parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
F i L wrote:
 Dmitry Olshansky wrote:
 Hm... If placed at the global scope it looks like a namespace.

I don't see anything wrong with that. It's just another way (somewhat unique to D) you can categorize your code. Most people probably won't use this sort of thing all over the place, but it actually might be useful for "enforcing" naming classifications: // File system/io.d template Console { void write( ... ) void read() }

final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)
Oct 05 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/5/12 5:28 PM, Paulo Pinto wrote:
 Time to write "D the good parts" or "Effective D" ?

"D the good parts" would be much bigger than TDPL :o). Andrei
Oct 05 2012
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
Dmitry Olshansky wrote:
 Hm... If placed at the global scope it looks like a namespace.

I don't see anything wrong with that. It's just another way (somewhat unique to D) you can categorize your code. Most people probably won't use this sort of thing all over the place, but it actually might be useful for "enforcing" naming classifications: // File system/io.d template Console { void write( ... ) void read() } template File { void write( ... ) void read() } // File something.d import system.io; void main() { // Prefix 'Console/File' required so to the // user, it looks somewhat like a static object Console.write( ... ); File.write( ... ); }
Oct 05 2012
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 5 October 2012 at 20:19:26 UTC, Piotr Szturmaj wrote:
 F i L wrote:
 Dmitry Olshansky wrote:
 Hm... If placed at the global scope it looks like a namespace.

I don't see anything wrong with that. It's just another way (somewhat unique to D) you can categorize your code. Most people probably won't use this sort of thing all over the place, but it actually might be useful for "enforcing" naming classifications: // File system/io.d template Console { void write( ... ) void read() }

final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)

Thanks to how dmd parses code, many simultaneous things actually work, sometimes it is nonsense http://dpaste.dzfl.pl/04e6bf33
Oct 05 2012
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
Piotr Szturmaj wrote:
 final abstract class Console
 {
     static:
     void write() { }
     void read() { }
 }

 Console.write();

 P.S. Yes, simultaneous final and abstract actually works :)

Yes, I know there are other ways to do this, like you mentioned above. However, parameter-less templates would still be nice for scopes withing a Class (like my original example). Like I mentioned, it's possible today: class Foo { int bar; alias Baz!() baz; template Baz() { int bar; } } auto foo = new Foo(); foo.bar = 10; foo.baz.bar = 10; // Same as.. foo.Baz!().bar = 10; // ..writing this. However, like OP is suggesting, it would be nice to have syntax-sugar to eliminate the need for extra typing at instantiation and at definition (my suggestion). The fact that these odd '!()' symbols are required will probably detour less-experienced people from using this feature today.
Oct 05 2012
prev sibling next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Friday, 5 October 2012 at 20:42:06 UTC, Maxim Fomin wrote:
 On Friday, 5 October 2012 at 20:19:26 UTC, Piotr Szturmaj wrote:
 F i L wrote:
 Dmitry Olshansky wrote:
 Hm... If placed at the global scope it looks like a 
 namespace.

I don't see anything wrong with that. It's just another way (somewhat unique to D) you can categorize your code. Most people probably won't use this sort of thing all over the place, but it actually might be useful for "enforcing" naming classifications: // File system/io.d template Console { void write( ... ) void read() }

final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)

Thanks to how dmd parses code, many simultaneous things actually work, sometimes it is nonsense http://dpaste.dzfl.pl/04e6bf33

Time to write "D the good parts" or "Effective D" ?
Oct 05 2012
prev sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Friday, 5 October 2012 at 21:47:06 UTC, Andrei Alexandrescu 
wrote:
 On 10/5/12 5:28 PM, Paulo Pinto wrote:
 Time to write "D the good parts" or "Effective D" ?

"D the good parts" would be much bigger than TDPL :o). Andrei

I forgot the smiley Andrei. :)
Oct 06 2012