www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Empty array and AA literals

reply "dnspies" <dspies ualberta.ca> writes:
What's the syntax for a new empty dynamic array or associative 
array?

Every time I want to set a AA, I have to say:
(supposing I already have some variable int[int] aa which points 
to the wrong one)

int[int] throwaway;
aa = throwaway;

Is  there a way to say something like:

aa = new int[int] ?

like I would with a class.

What about for a normal dynamic array?
Apr 05 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
You can just set it to null. Then, next time you add anything to 
it, a new one will be automatically created.
Apr 05 2014
parent reply "dnspies" <dspies ualberta.ca> writes:
On Sunday, 6 April 2014 at 03:23:17 UTC, Adam D. Ruppe wrote:
 You can just set it to null. Then, next time you add anything 
 to it, a new one will be automatically created.
What about if I have a 2D array (ie int[][]) and I want to append an empty int[] on the end? Will this work? int[][] nested; nested ~= null; ~ is overloaded, so how does it know what type I intend null to be? How can I specify it?
Apr 05 2014
next sibling parent "Chris Nicholson-Sauls" <ibisbasenji gmail.com> writes:
On Sunday, 6 April 2014 at 03:28:50 UTC, dnspies wrote:
 On Sunday, 6 April 2014 at 03:23:17 UTC, Adam D. Ruppe wrote:
 You can just set it to null. Then, next time you add anything 
 to it, a new one will be automatically created.
What about if I have a 2D array (ie int[][]) and I want to append an empty int[] on the end? Will this work? int[][] nested; nested ~= null; ~ is overloaded, so how does it know what type I intend null to be? How can I specify it?
For dynamic arrays you can use the new operator. nested ~= new int[]; Or in this case, you could just increment the length. ++nested.length;
Apr 06 2014
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
dnspies:

 What about if I have a 2D array (ie int[][]) and I want to 
 append an empty int[] on the end?  Will this work?

 int[][] nested;

 nested ~= null;

 ~ is overloaded, so how does it know what type I intend null to 
 be?  How can I specify it?
You can increase by one of the length of the outer array, or you can append an empty one: nested.length++; or: nested ~= []; I don't remember if you can also append a null. Appending a null, if it works, could be more efficient. Take a look at the ASM. Bye, bearophile
Apr 06 2014
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 6 April 2014 at 09:41:10 UTC, bearophile wrote:
 dnspies:

 What about if I have a 2D array (ie int[][]) and I want to 
 append an empty int[] on the end?  Will this work?

 int[][] nested;
[...]
 You can increase by one of the length of the outer array, or 
 you can append an empty one:
[...]
 nested ~= [];
That doesn't add an element. [] is interpreted to be an empty int[][]. You need to write [[]] which is an int[][] holding one empty int[].
Apr 06 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
anonymous:

 You can increase by one of the length of the outer array, or 
 you can append an empty one:
[...]
 nested ~= [];
That doesn't add an element. [] is interpreted to be an empty int[][]. You need to write [[]] which is an int[][] holding one empty int[].
Thank you catching my mistake. But adding a null increases the length by 1: a ~= null; This difference is another reason for me to desire the removal of "null" as array literal. Bye, bearophile
Apr 06 2014
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/06/2014 05:28 AM, dnspies wrote:
 int[][] nested;

 nested ~= null;

 ~ is overloaded, so how does it know what type I intend null to be?  How
 can I specify it?
(int[]).init
Apr 06 2014
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 6 April 2014 at 03:17:25 UTC, dnspies wrote:
 What's the syntax for a new empty dynamic array or associative 
 array?

 Every time I want to set a AA, I have to say:
 (supposing I already have some variable int[int] aa which 
 points to the wrong one)

 int[int] throwaway;
 aa = throwaway;

 What about for a normal dynamic array?
AA's and Dynamic Arrays are different beasts. An Dynamic Array is merelly a "fat pointer" that holds both pointer and length. There is no need to create or new a Dynamic Array. An AA, on the other hand, is completely different. It's a pointer to an implementation, and the implementation does the actual work. The AA lazily initializes on the first operations. However, until initialized, an AA is pretty much just a null pointer. This can lead to interesting scenarios such as: //---- int[int] a; //null int[int] b = a; //both null assert(a is b); //They are both null a[1] = 1; //a gets initialized assert(a !is b); //but b remains null. int[int] c = a; //c points to the same implementation a[2] = 2; //a's implementation is changed assert(a is c); //and c "sees" it. //----
 Is  there a way to say something like:

 aa = new int[int] ?

 like I would with a class.
Currently, no. However, you can force initialization with a dummy insertion: int[int] b = [1:1]; b.remove(1); //b is now an empty, but initialized, AA It's a bit dirty, but that's how it is.
Apr 06 2014
parent reply "JR" <sunspyre gmail.com> writes:
On Sunday, 6 April 2014 at 09:52:04 UTC, monarch_dodra wrote:
 An Dynamic Array is merelly a "fat pointer" that holds both 
 pointer and length. There is no need to create or new a Dynamic 
 Array.
new allows for setting the length immediately, though. auto arr = new int[](99); // arr.length = 99; // avoided this Does doing it in two steps allocate twice?
Apr 06 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 6 April 2014 at 19:48:37 UTC, JR wrote:
 On Sunday, 6 April 2014 at 09:52:04 UTC, monarch_dodra wrote:
 An Dynamic Array is merelly a "fat pointer" that holds both 
 pointer and length. There is no need to create or new a 
 Dynamic Array.
new allows for setting the length immediately, though.
Right, but what I'm getting at, in regards to the original question: "What's the syntax for a new empty dynamic array" You don't "new" the dynamic array. Technically, you just allocate memory, and then have your *slice* reference that memory. The slice itself is not newed. An empty slice is merely a slice that reference no data. It just "exists" and is not "newed". This is in contrast to, say, classes, where you *must* do "A a = new A(args)" to initialize and use it. And yet even more in contrast to types that "look" like value types, but are "secretly" implemented as reference types, without the "new" keyword: Types that use reference semantic, but without the "new" keyword. These include: AA, Appender, Array, and a couple others.
      auto arr = new int[](99);
      // arr.length = 99;  // avoided this

 Does doing it in two steps allocate twice?
Nope. That's perfectly valid (and recomended).
Apr 06 2014
parent reply "JR" <zorael gmail.com> writes:
On Sunday, 6 April 2014 at 20:14:41 UTC, monarch_dodra wrote:
 Right, but what I'm getting at, in regards to the original 
 question:
 "What's the syntax for a new empty dynamic array"

 You don't "new" the dynamic array. Technically, you just 
 allocate memory, and then have your *slice* reference that 
 memory. The slice itself is not newed.
Aye, I'm just saying that there's *incentive* to new it, since it allows for reducing the two steps of declaration and setting the length into one. (and does compile without warning, at least with dmd)
 Does doing it in two steps allocate twice?
Nope. That's perfectly valid (and recomended).
You'll have to agree though that, by analogy, it's not unlike separating declaration from instantiation. SomeClass sc; sc = new SomeClass(); string foo; foo = "moo"; int[] arr; arr.length = 5; I would not object to a syntax like T[](length), myself. My main pet peeve remains array literals being dynamic.
Apr 09 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 9 April 2014 at 09:33:47 UTC, JR wrote:
 Does doing it in two steps allocate twice?
Nope. That's perfectly valid (and recomended).
You'll have to agree though that, by analogy, it's not unlike separating declaration from instantiation. [...] I would not object to a syntax like T[](length), myself.
I *think* there was some miscommunication here: auto arr = new int[](99); Is perfectly valid, and the recommended way to do it (provided you know how much you want to allocate when constructing).
 My main pet peeve remains array literals being dynamic.
What do you mean? Perhaps you meant you wanted to allocate a static array on the heap? EG, "int[99]* p = new ???;" Otherwise, I don't really understand the statement.
Apr 09 2014
parent "JR" <zorael gmail.com> writes:
On Wednesday, 9 April 2014 at 16:46:00 UTC, monarch_dodra wrote:
 I *think* there was some miscommunication here:
 auto arr = new int[](99);

 Is perfectly valid, and the recommended way to do it (provided 
 you know how much you want to allocate when constructing).
Looks like it. :) The flow of conversation reads to me like so: 1. "There's no need to new or create a dynamic array" 2. "But newing allows for setting the length immediately though. <example>. Does doing it in two steps (declaring, then setting length) allocate twice?" 3. "No, [doing it in two steps] is perfectly valid (and recommended), [with valid meaning you're not double-allocating for no reason]" 4. "I see, but if [doing it in two steps] is recommended and there's no need to new, you'll have to agree that newing is still alluring etc etc"
 My main pet peeve remains array literals being dynamic.
What do you mean? Perhaps you meant you wanted to allocate a static array on the heap? EG, "int[99]* p = new ???;" Otherwise, I don't really understand the statement.
Different topic, but I mean !is(typeof([1, 2, 3]) == int[3]). Nothing that can't be danced around, yet a peeve nonetheless.
Apr 09 2014