Thread overview
Array initializers and inheritance
Oct 29, 2006
Max Bolingbroke
Oct 30, 2006
Bill Baxter
Nov 04, 2006
Stewart Gordon
October 29, 2006
Hi,

I have an array declared like so:

private GameObject[] _gameObjects;

And an inheritance hierarchy like this:

class Player : GameObject
{ ... }

class Target : GameObject
{ ... }

When I do this:

_gameObjects = [new Player(),
                new Target(Direction.Up, 0, 0)];

I get a compile error (Target cannot be cast to Player). But when I do this:

_gameObjects = [cast(GameObject)(new Player()),
                new Target(Direction.Up, 0, 0)];

It works! Is this by design? It is not clear to me from reading the specification.

Thanks,

Max
October 29, 2006
I think, the array initialization feature is not so nice. The array takes its type from the type of the first initializer. This is absolutely ugly.

I would prefer if you can write this
_gameObjects = new GameObject [ new Player(), new Target(Direction.Up,
0, 0)];

The second bad thing is, they tend to generate static arrays. So often you need to append a [] to convert the static array into a dynamic one.

When generating D code, i use array initialization and cast every member to the type of the array element and append [] to every such initializer. This code looks really ugly.

@W Please rethink this syntax :)

Or did I really missed the "good way of array initialization"?




October 30, 2006
Frank Benoit (keinfarbton) wrote:
> I think, the array initialization feature is not so nice. The array
> takes its type from the type of the first initializer. This is
> absolutely ugly.

You are correct that it takes its type from the first element.  In the vast majority of cases (personal experience, might not be general) this hasn't been a problem.  Still, I do feel a little antsy sometimes about putting that cast() at the beginning.

> I would prefer if you can write this
> _gameObjects = new GameObject [ new Player(), new Target(Direction.Up,
> 0, 0)];

If one uses the CashewUtils array library (cashew.utils.array, available from DSource) then you can do:
# _gameObjects = array!(GameObject)(new Player, new Target(Direction.Up, 0, 0));

Still not perfeclty ideal, of course.  This is my current personal (biased) preferance. ;)

> The second bad thing is, they tend to generate static arrays. So often
> you need to append a [] to convert the static array into a dynamic one.

As far as I know, this shouldn't be neccesary.  If I remember right, static arrays implicitly cast to dynamic arrays (but not the other way around).  In fact, the extra [] at the end doesn't cast the array at all, but rather takes a full slice of it.  Which still has the desired effect, but...

> When generating D code, i use array initialization and cast every member
> to the type of the array element and append [] to every such
> initializer. This code looks really ugly.

You only have to cast the first one, as this is what determines the array's type.

-- Chris Nicholson-Sauls
October 30, 2006
Chris Nicholson-Sauls wrote:
> Frank Benoit (keinfarbton) wrote:
>> I think, the array initialization feature is not so nice. The array
>> takes its type from the type of the first initializer. This is
>> absolutely ugly.
> 
> You are correct that it takes its type from the first element.  In the vast majority of cases (personal experience, might not be general) this hasn't been a problem.  Still, I do feel a little antsy sometimes about putting that cast() at the beginning.

To me that is fairly surprising behavior.  I would expect the compiler to look at *all* the values in the array literal and pick the type to use based on standard promotion rules ("integer promotions" and "usual arithmetic conversions" from http://www.digitalmars.com/d/type.html).

I.e. [1, 2, 3, 4.0] should be double[4], not int[4].

Just like 1+2+3+4.0 is a double and not and int.

--bb
November 04, 2006
Frank Benoit (keinfarbton) wrote:
> I think, the array initialization feature is not so nice. The array
> takes its type from the type of the first initializer. This is
> absolutely ugly.

That's not initialization, that's array literals.

> I would prefer if you can write this
> _gameObjects = new GameObject [ new Player(), new Target(Direction.Up,
> 0, 0)];

That would create a parsing ambiguity.

But I agree that it would be nice if you could give the type of an array literal explicitly.  This syntax was suggested at least once:

    _gameObjects = new GameObject[]!
      [ new Player(), new Target(Direction.Up, 0, 0)];

> The second bad thing is, they tend to generate static arrays. So often
> you need to append a [] to convert the static array into a dynamic one.
> 
> When generating D code, i use array initialization and cast every member
> to the type of the array element and append [] to every such
> initializer. This code looks really ugly.
> 
> @W Please rethink this syntax :)

My thought is that the programmer should have the choice of implicitly-typed or explicitly-typed array literals.  And that implicitly-typed array literals should be simultaneously of every type to which every element is implicitly convertible, in much the same way as string literals are simultaneously of types char[], wchar[] and dchar[].  And be simultaneously of static and dynamic array types.

So for example,

    [ 42, 0, 6789 ]

would be of the following types:

short[3]
short[]
ushort[3]
ushort[]
int[3]
int[]
uint[3]
uint[]
long[3]
long[]
ulong[3]
ulong[]

and that's before you count the floating-point and complex versions....

> Or did I really missed the "good way of array initialization"?

Pardon?

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.