digitalmars.D - initializers
- John C (52/52) Sep 18 2005 I know array initializers are coming post-1.0, but how about allowing
- Chris Sauls (30/98) Sep 19 2005 I do see your idea, and it is kind of nifty... But I see two things. T...
- John C (8/111) Sep 19 2005 What if the class had to derive from a standard interface declaring thos...
- Chris Sauls (14/28) Sep 19 2005 I hadn't thought of that, but it could work. Something like:
I know array initializers are coming post-1.0, but how about allowing array-like initialization on array-like classes - specifically, classes that implement opIndex/opIndexAssign as well as a contructor that specifies the size of its elements. Example: class List(T) { this(int size) ... T opIndex(int index) ... void opIndexAssign(T val, int index) ... } List!(int) list = [ 1, 12, 123 ]; or perhaps List!(int) list = new List!(int) [ 1, 12, 123 ]; This would be the equivalent of: List!(int) list = new List!(int)(3); list[0] = 1; list[1] = 12; list[2] = 123; While a template could do the initialization, the syntax is more consistent with how arrays will work. Also, when/if non-static struct initializers are implemented, perhaps object initializers could be added to the language. Example: enum Genre { ROCK, POP, CLASSICAL } class Song { private Genre genre_; char[] title; char[] artist; Genre genre() { return genre_; } void genre(Genre val) { genre_ = val; } } Song song2 = { title: "Song2", artist: "Blur", genre: Genre.ROCK }; // should work only for public properties and fields Which would be the same as this: Song song2 = new Song; song2.title = "Song2"; song2.artist = "Blur"; song2.genre = Genre.ROCK; Now, obviously a class constructor could do the work, but most classes don't have constructors for every field/property. Join both concepts together and you have a very nice syntax for creating collections. List!(Song) compilation = [ new Song { title = "Speed of Sound", artist = "Coldplay", genre = Genre.ROCK }, new Song { title = "King Tide", artist = "Neil Finn", genre = Genre.POP } ]; No sassy comments about my taste in music, but feel free to tear this idea down.
Sep 18 2005
John C wrote:I know array initializers are coming post-1.0, but how about allowing array-like initialization on array-like classes - specifically, classes that implement opIndex/opIndexAssign as well as a contructor that specifies the size of its elements. Example: class List(T) { this(int size) ... T opIndex(int index) ... void opIndexAssign(T val, int index) ... } List!(int) list = [ 1, 12, 123 ]; or perhaps List!(int) list = new List!(int) [ 1, 12, 123 ]; This would be the equivalent of: List!(int) list = new List!(int)(3); list[0] = 1; list[1] = 12; list[2] = 123; While a template could do the initialization, the syntax is more consistent with how arrays will work.I do see your idea, and it is kind of nifty... But I see two things. The first, lesser, argument is that it could be provided (yes I know, this doesn't make it universal) via a static instantiator method using typesafe variadics. Aka, something like this: Or you could be really cute and make it a static opCall overload, leading to this syntax: And you could also use a static opIndex overload to get a syntax somewhat like your proposal: Although now I'm just being rediculous. The second, greater, argument is that, frankly, how should the compiler determine whether or not this syntax is semantically valid for a given class? You listed three (really two) requirements. 1 - opIndex/opIndexAssign overloads 2 - a constructor that takes a size Number 1 is easy as pie (easier, even) to check for! But number two is the problem. How does the compiler know that a given constructor taking an integral parameter is in fact a size/length/capacity setting constructor? The only way I can think of is by decoration, but that means adding a new attribute that really only serves a single, small, uncommonly used feature.Also, when/if non-static struct initializers are implemented, perhaps object initializers could be added to the language. Example: enum Genre { ROCK, POP, CLASSICAL } class Song { private Genre genre_; char[] title; char[] artist; Genre genre() { return genre_; } void genre(Genre val) { genre_ = val; } } Song song2 = { title: "Song2", artist: "Blur", genre: Genre.ROCK }; // should work only for public properties and fields Which would be the same as this: Song song2 = new Song; song2.title = "Song2"; song2.artist = "Blur"; song2.genre = Genre.ROCK; Now, obviously a class constructor could do the work, but most classes don't have constructors for every field/property. Join both concepts together and you have a very nice syntax for creating collections. List!(Song) compilation = [ new Song { title = "Speed of Sound", artist = "Coldplay", genre = Genre.ROCK }, new Song { title = "King Tide", artist = "Neil Finn", genre = Genre.POP } ];Now this, in general, actually does look interesting/promising. There should be a way to accomplish something like this. -- Chris Sauls
Sep 19 2005
"Chris Sauls" <ibisbasenji gmail.com> wrote in message news:dgls4u$160m$1 digitaldaemon.com...John C wrote:What if the class had to derive from a standard interface declaring those functions? There's a precedent for this: IUnknown, which the compiler treats specially.I know array initializers are coming post-1.0, but how about allowing array-like initialization on array-like classes - specifically, classes that implement opIndex/opIndexAssign as well as a contructor that specifies the size of its elements. Example: class List(T) { this(int size) ... T opIndex(int index) ... void opIndexAssign(T val, int index) ... } List!(int) list = [ 1, 12, 123 ]; or perhaps List!(int) list = new List!(int) [ 1, 12, 123 ]; This would be the equivalent of: List!(int) list = new List!(int)(3); list[0] = 1; list[1] = 12; list[2] = 123; While a template could do the initialization, the syntax is more consistent with how arrays will work.I do see your idea, and it is kind of nifty... But I see two things. The first, lesser, argument is that it could be provided (yes I know, this doesn't make it universal) via a static instantiator method using typesafe variadics. Aka, something like this: Or you could be really cute and make it a static opCall overload, leading to this syntax: And you could also use a static opIndex overload to get a syntax somewhat like your proposal: Although now I'm just being rediculous. The second, greater, argument is that, frankly, how should the compiler determine whether or not this syntax is semantically valid for a given class? You listed three (really two) requirements. 1 - opIndex/opIndexAssign overloads 2 - a constructor that takes a size Number 1 is easy as pie (easier, even) to check for! But number two is the problem. How does the compiler know that a given constructor taking an integral parameter is in fact a size/length/capacity setting constructor? The only way I can think of is by decoration, but that means adding a new attribute that really only serves a single, small, uncommonly used feature.Yes, the main thing is to make it easier to create lists. Most languages (apart from C/C++ and their derivatives) have some kind of built-in support for list initialization.Also, when/if non-static struct initializers are implemented, perhaps object initializers could be added to the language. Example: enum Genre { ROCK, POP, CLASSICAL } class Song { private Genre genre_; char[] title; char[] artist; Genre genre() { return genre_; } void genre(Genre val) { genre_ = val; } } Song song2 = { title: "Song2", artist: "Blur", genre: Genre.ROCK }; // should work only for public properties and fields Which would be the same as this: Song song2 = new Song; song2.title = "Song2"; song2.artist = "Blur"; song2.genre = Genre.ROCK; Now, obviously a class constructor could do the work, but most classes don't have constructors for every field/property. Join both concepts together and you have a very nice syntax for creating collections. List!(Song) compilation = [ new Song { title = "Speed of Sound", artist = "Coldplay", genre = Genre.ROCK }, new Song { title = "King Tide", artist = "Neil Finn", genre = Genre.POP } ];Now this, in general, actually does look interesting/promising. There should be a way to accomplish something like this. -- Chris Sauls
Sep 19 2005
John C wrote:"Chris Sauls" <ibisbasenji gmail.com> wrote in message news:dgls4u$160m$1 digitaldaemon.com...I hadn't thought of that, but it could work. Something like: -- Chris SaulsNumber 1 is easy as pie (easier, even) to check for! But number two is the problem. How does the compiler know that a given constructor taking an integral parameter is in fact a size/length/capacity setting constructor? The only way I can think of is by decoration, but that means adding a new attribute that really only serves a single, small, uncommonly used feature.What if the class had to derive from a standard interface declaring those functions? There's a precedent for this: IUnknown, which the compiler treats specially.
Sep 19 2005