digitalmars.D - Implicit instantiation of parameterless templates
- Piotr Szturmaj (17/17) Oct 05 2012 Java and C# with their generics can do the following:
- Paulo Pinto (8/27) Oct 05 2012 Why to you need this?
- Piotr Szturmaj (7/38) Oct 05 2012 For convenience. In the above example, List without parameters could
- David Piepgrass (13/30) Oct 05 2012 The Java and C# situations are very different. In Java, generics
- F i L (20/39) Oct 05 2012 +1 This is natural.
- Dmitry Olshansky (4/49) Oct 05 2012 Hm... If placed at the global scope it looks like a namespace.
- F i L (25/26) Oct 05 2012 I don't see anything wrong with that. It's just another way
- Piotr Szturmaj (9/21) Oct 05 2012 final abstract class Console
- Maxim Fomin (3/30) Oct 05 2012 Thanks to how dmd parses code, many simultaneous things actually
- Paulo Pinto (2/37) Oct 05 2012 Time to write "D the good parts" or "Effective D" ?
- Andrei Alexandrescu (3/4) Oct 05 2012 "D the good parts" would be much bigger than TDPL :o).
- Paulo Pinto (3/7) Oct 06 2012 I forgot the smiley Andrei. :)
- F i L (23/31) Oct 05 2012 Yes, I know there are other ways to do this, like you mentioned
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
On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote: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? 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
Paulo Pinto wrote:On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote: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.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?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
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:...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? compatibility, because their first version did not allow for generics, and their creators did not want to force everyone to recode their code bases.are "erased" at runtime so a List<int> is the same thing as a 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 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
On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote: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
On 05-Oct-12 23:25, F i L wrote:On Friday, 5 October 2012 at 12:01:30 UTC, Piotr Szturmaj wrote:Hm... If placed at the global scope it looks like a namespace. -- Dmitry Olshanskyclass 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
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
F i L wrote:Dmitry Olshansky wrote:final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)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() }
Oct 05 2012
On Friday, 5 October 2012 at 20:19:26 UTC, Piotr Szturmaj wrote:F i L wrote:Thanks to how dmd parses code, many simultaneous things actually work, sometimes it is nonsense http://dpaste.dzfl.pl/04e6bf33Dmitry Olshansky wrote:final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)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() }
Oct 05 2012
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:Time to write "D the good parts" or "Effective D" ?F i L wrote:Thanks to how dmd parses code, many simultaneous things actually work, sometimes it is nonsense http://dpaste.dzfl.pl/04e6bf33Dmitry Olshansky wrote:final abstract class Console { static: void write() { } void read() { } } Console.write(); P.S. Yes, simultaneous final and abstract actually works :)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() }
Oct 05 2012
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
On Friday, 5 October 2012 at 21:47:06 UTC, Andrei Alexandrescu wrote:On 10/5/12 5:28 PM, Paulo Pinto wrote:I forgot the smiley Andrei. :)Time to write "D the good parts" or "Effective D" ?"D the good parts" would be much bigger than TDPL :o). Andrei
Oct 06 2012
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