digitalmars.D.learn - Array initialization with common base - Best way?
- deadimp (17/17) Nov 08 2008 What's a 'good' way to initialize an array of references to classes usin...
- =?windows-1252?Q?=22J=E9r=F4me_M=2E_Berger=22?= (21/40) Nov 09 2008 -----BEGIN PGP SIGNED MESSAGE-----
- deadimp (5/14) Nov 09 2008 That's the problem I had mentioned, though - the type of the entire arra...
- Ary Borenszweig (7/25) Nov 09 2008 Can't the compiler try to set the array's component type to the most
- Bill Baxter (18/24) Nov 09 2008 I'm not sure what the problem is. I think Walter likes the current
- deadimp (3/21) Nov 09 2008 Mebbe the naiive expectations arise because most compilers (those for D,...
- Carl Clark (3/4) Nov 10 2008 I believe it's called type promotion (see
- Ary Borenszweig (32/69) Nov 10 2008 Ok, I wanted to see what does C# do with this. C# has the "var" keyword
What's a 'good' way to initialize an array of references to classes using a common base? I've tried this and it works: class Base { void func(); } class GoodChild : Base { void func(); } class BadChild : Base { void func(); } //... auto list = [cast(Base)new GoodChild, new BadChild, ...]; I had tried doing it without the initial cast, but ran into issues because D (DMD v1.033) would infer the type based off of the first element in the literal, and then assumed that all other elements would be the same.
Nov 08 2008
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 deadimp wrote:What's a 'good' way to initialize an array of references to classes using a common base? I've tried this and it works: class Base { void func(); } class GoodChild : Base { void func(); } class BadChild : Base { void func(); } //... auto list = [cast(Base)new GoodChild, new BadChild, ...]; I had tried doing it without the initial cast, but ran into issues because D (DMD v1.033) would infer the type based off of the first element in the literal, and then assumed that all other elements would be the same.I would replace the last line with: Base[] list = [ new GoodChild, new BadChild, ...]; It's clearer, there's less typing and it won't suddenly fail if you remove the first element and accidentally remove the cast at the same time or if you add a new first element and forget to add the cast... Jerome - -- +------------------------- Jerome M. BERGER ---------------------+ | mailto:jeberger free.fr | ICQ: 238062172 | | http://jeberger.free.fr/ | Jabber: jeberger jabber.fr | +---------------------------------+------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkkWvUEACgkQd0kWM4JG3k/+lQCfTvFvrT5CmEhC0z5r11Esj5Cv IckAn1csTb5QyDZr2icXHfDKqYDMKC0w =SXsh -----END PGP SIGNATURE-----
Nov 09 2008
That's the problem I had mentioned, though - the type of the entire array being inferred from the first element rather than the context (i.e. what it's initializing if not declared as 'auto') or subsequent elements (which would be a bit difficult...). When I try that, the compiler prints this error message: (formatted for this context) "Error: cannot implicitly convert expression (new BadChild) of type BadChild to GoodChild" instantiations wouldn't really fit in syntactically with the already established style of arrays. But maybe there's a way the type of an array coud be explicitly stated without having to cast to make the type inference correct. Jérôme M. Berger Wrote:I would replace the last line with: Base[] list = [ new GoodChild, new BadChild, ...]; It's clearer, there's less typing and it won't suddenly fail if you remove the first element and accidentally remove the cast at the same time or if you add a new first element and forget to add the cast... Jerome
Nov 09 2008
deadimp escribió:That's the problem I had mentioned, though - the type of the entire array being inferred from the first element rather than the context (i.e. what it's initializing if not declared as 'auto') or subsequent elements (which would be a bit difficult...). When I try that, the compiler prints this error message: (formatted for this context) "Error: cannot implicitly convert expression (new BadChild) of type BadChild to GoodChild" array instantiations wouldn't really fit in syntactically with the already established style of arrays. But maybe there's a way the type of an array coud be explicitly stated without having to cast to make the type inference correct. Jérôme M. Berger Wrote:Can't the compiler try to set the array's component type to the most general type of it's elements, by combining the most general types by pairs? Hmmm... now that I think it, it's not that easy because of interfaces. Did this subject was ever discussed? If not, I'll try to think of an algorithm for this. (because if it was discussed, there must be a good reason for not doing this)I would replace the last line with: Base[] list = [ new GoodChild, new BadChild, ...]; It's clearer, there's less typing and it won't suddenly fail if you remove the first element and accidentally remove the cast at the same time or if you add a new first element and forget to add the cast... Jerome
Nov 09 2008
On Mon, Nov 10, 2008 at 6:47 AM, Ary Borenszweig <ary esperanto.org.ar> wrote:Can't the compiler try to set the array's component type to the most general type of it's elements, by combining the most general types by pairs? Hmmm... now that I think it, it's not that easy because of interfaces. Did this subject was ever discussed? If not, I'll try to think of an algorithm for this. (because if it was discussed, there must be a good reason for not doing this)I'm not sure what the problem is. I think Walter likes the current scheme because it's simple for the compiler and simple to explain. Unfortunately I think it is counter to naive expectations, which means that even though it's simple to explain, it *has* to be explained to the uninitiated. NumPy works the way you suggest. It picks the most generic type that can hold the answer. I'm not sure what the algorithm is but it seems to give adhere much better to the principle of least surprise. But maybe the fact that NumPy only cares about numeric types makes the problem easier. But I should would like it if this worked auto foo = [1,1,1,0.5]; and gave me a double[]. Anyway, that behavior seems to do what most people expeect. On the other hand I've seen this topic of picking the first element's type come up several times here, generally because people didn't expect that behavior.. --bb
Nov 09 2008
Mebbe the naiive expectations arise because most compilers (those for D, C++, general 'blanketing' type - even though the first operand is an int. I forgot what this concept was called, though... I would at least expect it when the variable has the type explicitly declared (`Base[] list`), since the following list would be seen as an initialization... Or is there another way that you initialize arrays, be they static or dynamic? Bill Baxter Wrote:I'm not sure what the problem is. I think Walter likes the current scheme because it's simple for the compiler and simple to explain. Unfortunately I think it is counter to naive expectations, which means that even though it's simple to explain, it *has* to be explained to the uninitiated. NumPy works the way you suggest. It picks the most generic type that can hold the answer. I'm not sure what the algorithm is but it seems to give adhere much better to the principle of least surprise. But maybe the fact that NumPy only cares about numeric types makes the problem easier. But I should would like it if this worked auto foo = [1,1,1,0.5]; and gave me a double[]. Anyway, that behavior seems to do what most people expeect. On the other hand I've seen this topic of picking the first element's type come up several times here, generally because people didn't expect that behavior.. --bb
Nov 09 2008
On 2008-11-09 19:50, deadimp wrote:Mebbe the naiive expectations arise because most compilers (those for D, C++, general 'blanketing' type - even though the first operand is an int. I forgot what this concept was called, though...I believe it's called type promotion (see http://en.wikipedia.org/wiki/Type_polymorphism#Overloading).
Nov 10 2008
Ary Borenszweig wrote:deadimp escribió:that has the same semantic as "auto". Also, it has array initializers, and today I found they come in two flavors: { x, y, z } --> don't use type inference new [] { x, y, z } --> use type inference I can see the type of a "var" variable by hovering over it in Visual Studio. Let's see: var x = { 1, 2, 3 }; // Error: cannot initialize an implicitly-typed // local variable with an array initializer var x = new [] { 1, 2, 3 }; // ok, x is Int32[] var x = new [] { 1, 2.0, 3 }; // ok, x is Double[] Now with classes (object is root of all classes). class A { } class B { } var x = new [] { new object(), new A() }; // ok, x is Object[] var x = new [] { new A(), new B() }; // Error: no base type for implicitly typed array (the question here is, why not infer object[]?) Without type deduction: object[] x = new [] { new A(), new B() }; // Error: no base type for implicitly typed array But, without new []: object[] x = { new A(), new B() }; // ok In this last example, although no type can be inferred for the array initializer, the compiler can see that each of it's elements can be cast to object, and so doesn't give a compile error. Why not implement this last behavior in D? I think this is a very common case, and it seems easy to implement. I'll try to debug DMD's source code at night to see what can be changed for this to work... if there's interest.That's the problem I had mentioned, though - the type of the entire array being inferred from the first element rather than the context (i.e. what it's initializing if not declared as 'auto') or subsequent elements (which would be a bit difficult...). When I try that, the compiler prints this error message: (formatted for this context) "Error: cannot implicitly convert expression (new BadChild) of type BadChild to GoodChild" new array instantiations wouldn't really fit in syntactically with the already established style of arrays. But maybe there's a way the type of an array coud be explicitly stated without having to cast to make the type inference correct. Jérôme M. Berger Wrote:Can't the compiler try to set the array's component type to the most general type of it's elements, by combining the most general types by pairs? Hmmm... now that I think it, it's not that easy because of interfaces. Did this subject was ever discussed? If not, I'll try to think of an algorithm for this. (because if it was discussed, there must be a good reason for not doing this)I would replace the last line with: Base[] list = [ new GoodChild, new BadChild, ...]; It's clearer, there's less typing and it won't suddenly fail if you remove the first element and accidentally remove the cast at the same time or if you add a new first element and forget to add the cast... Jerome
Nov 10 2008