www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What is the current point to empty/null associative arrays?

reply "Cooler" <kulkin hotbox.ru> writes:
First - I search the forum for discussion on my question, but all 
talks ends with nothing.
Therefore again:

import std.stdio;

void fillArray(string[int] a){ a[10] = "A"; }

void main(){
   string[int] b;
   fillArray(b); // Here we expect b gets new element [10:"A"], 
but...
   writeln(b); // Prints [] (empty array)

   b[1] = "B";
   fillArray(b);
   writeln(b); // Prints [1:"B", 10:"A"] (OK, expected behaviour)
}

In the first call fillArray() gets null AA and creates new one 
inside { a[10] = "A"; }, that will not be returned. After the 
call array b remains null.
In the second call fillArray() gets not-null AA and successfully 
add new element to it.
The problem can be solved if we have empty associative array 
initializer (aka string[int] b = [:]), as already discussed on 
this forum. Does any body knows what is the current situation 
with such initializers? Or may be described problem can be solved 
by other means?
Nov 29 2013
parent reply "Chris Cain" <clcain uncg.edu> writes:
On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Nov 29 2013
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
But on the other hand, AA array is sometimes affected without ref parameter, so advice to put ref does not explain per se the issue. Actually this is a good defficiency illustration of separation between value types and 'reference types' which are passed 'by reference'.
Nov 29 2013
prev sibling parent reply "Cooler" <kulkin hotbox.ru> writes:
On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
Nov 29 2013
parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Friday, 29 November 2013 at 09:39:57 UTC, Cooler wrote:
 On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
string[int]* aaToFill = someCheck ? &aa1 : &aa2; (*aaToFill)["A"] = 1;
Nov 29 2013
next sibling parent "Cooler" <kulkin hotbox.ru> writes:
On Friday, 29 November 2013 at 09:51:07 UTC, Peter Alexander
wrote:
 On Friday, 29 November 2013 at 09:39:57 UTC, Cooler wrote:
 On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
string[int]* aaToFill = someCheck ? &aa1 : &aa2; (*aaToFill)["A"] = 1;
You are right! But looks like a hack. If it will be something like empty initilizer [:], it will be better.
Nov 29 2013
prev sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Fri, 29 Nov 2013 09:51:05 -0000, Peter Alexander  
<peter.alexander.au gmail.com> wrote:

 On Friday, 29 November 2013 at 09:39:57 UTC, Cooler wrote:
 On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
string[int]* aaToFill = someCheck ? &aa1 : &aa2; (*aaToFill)["A"] = 1;
Resorting to pointers = fail (for the language) I'm afraid. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 29 2013
parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Friday, 29 November 2013 at 15:55:57 UTC, Regan Heath wrote:
 On Fri, 29 Nov 2013 09:51:05 -0000, Peter Alexander 
 <peter.alexander.au gmail.com> wrote:

 On Friday, 29 November 2013 at 09:39:57 UTC, Cooler wrote:
 On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
string[int]* aaToFill = someCheck ? &aa1 : &aa2; (*aaToFill)["A"] = 1;
Resorting to pointers = fail (for the language) I'm afraid. R
How so? Only pointer arithmetic is unsafe. Pointers themselves are perfectly fine and safe.
Nov 29 2013
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Sat, 30 Nov 2013 04:37:00 -0000, Peter Alexander  
<peter.alexander.au gmail.com> wrote:

 On Friday, 29 November 2013 at 15:55:57 UTC, Regan Heath wrote:
 On Fri, 29 Nov 2013 09:51:05 -0000, Peter Alexander  
 <peter.alexander.au gmail.com> wrote:

 On Friday, 29 November 2013 at 09:39:57 UTC, Cooler wrote:
 On Friday, 29 November 2013 at 08:48:03 UTC, Chris Cain wrote:
 On Friday, 29 November 2013 at 08:32:12 UTC, Cooler wrote:
 ...
Try making fill array look more like this: void fillArray(ref string[int] a) { a[10] = "A"; } The issue is that an array (and/or associative array) is a value type. Basically, you can look at it as a struct with a pointer (and some extra info). If you don't pass it as a ref then reallocations (such as what happens when you add an item to an empty AA) will cause the two to not point to the same information anymore.
Adding "ref" is not an exit. I show this example only for simplicity. In my real example I have to fill different AA base on condition: string[int] aa1, aa2; ... auto aaToFill = someCheck ? aa1 : aa2; // Then do something with aaToFill If aa1 is empty it will never be filled.
string[int]* aaToFill = someCheck ? &aa1 : &aa2; (*aaToFill)["A"] = 1;
Resorting to pointers = fail (for the language) I'm afraid. R
How so? Only pointer arithmetic is unsafe. Pointers themselves are perfectly fine and safe.
The code using pointers is unnecessarily ugly *IMO*. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 02 2013
parent reply "Cooler" <kulkin hotbox.ru> writes:
Stop hollywaring here.
The problem again...
There are two different states of an associative array - null and 
empty.
Null state is when we just define AA without initializers:
   string[int] aa;

Empty state can now be achieved if we add and then remove any key 
from null AA:
   string[int] aa;
   aa[0] = "";
   aa.remove(0);

It will be more convenient to define empty AA something like this:
   string[int] aa = [:];

The disscussion is on how to achive empty associative arrays. Is 
anybody going to extend D syntax to get the goal?
Dec 02 2013
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Mon, 02 Dec 2013 13:27:32 -0000, Cooler <kulkin hotbox.ru> wrote:

 Stop hollywaring here.
Yeah, we're not. I am simply expressing an opinion and I'm not really interested in the OP issue at this time. R
Dec 03 2013
parent "Cooler" <kulkin hotbox.ru> writes:
May be Walter Bright tell us his opinion?
Dec 06 2013