www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Are associative arrays stable in D?

reply "Gary Willoughby" <dev nomad.so> writes:
Are associative arrays stable in D? I have to ask because i'm 
having a great deal of problems with them for simple operations. 
For example the following crashes.

import std.stdio;

void main(string[] args)
{
	int[string] waiting;

	waiting["gary"] = 1;
	waiting["tess"] = 2;

	foreach (string key; waiting.byKey())
	{
		writeln(key);
		writeln(waiting[key]);
		waiting.remove(key);
	}
}

If however you remove the .byKey() call and use .keys instead, it 
works!

Also if you remove the 'writeln(waiting[key]);' line from the 
above code it prints about 40 blank lines.
Jul 16 2013
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, July 16, 2013 21:37:13 Gary Willoughby wrote:
 Are associative arrays stable in D? I have to ask because i'm
 having a great deal of problems with them for simple operations.
 For example the following crashes.
 
 import std.stdio;
 
 void main(string[] args)
 {
 int[string] waiting;
 
 waiting["gary"] = 1;
 waiting["tess"] = 2;
 
 foreach (string key; waiting.byKey())
 {
 writeln(key);
 writeln(waiting[key]);
 waiting.remove(key);
 }
 }
 
 If however you remove the .byKey() call and use .keys instead, it
 works!
 
 Also if you remove the 'writeln(waiting[key]);' line from the
 above code it prints about 40 blank lines.
It's not safe to remove anything from the AA while iterating over it. Doing so will invalidate the range. If you did foreach(auto key; waiting.keys()) { writeln(key); writeln(waiting[key]); waiting.remove(key); } then you'd be okay - either that or create a new array which you append the keys to that you want to remove and then have a second loop which loops over that array and removes each of the keys from the AA. In this particular case, since you're removing everything, it's probably more efficient to just allocate the array with all of them up front with keys(), but if you were only removing some of them, then it would probably be more efficient to create an array of the keys to remove and then iterate over those in a second loop. - Jonathan M davis
Jul 16 2013
prev sibling next sibling parent reply "Mike Parker" <aldacron gmail.com> writes:
On Tuesday, 16 July 2013 at 19:37:14 UTC, Gary Willoughby wrote:

 If however you remove the .byKey() call and use .keys instead, 
 it works!
With byKey, you are iterating over a range of original key values, meaning that attempting to remove any of them will result in bad bahavior. With .keys, you are iterating over a copied array of the keys, hence it's safe to remove them from the aa.
Jul 17 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 17 July 2013 at 08:31:00 UTC, Mike Parker wrote:
 On Tuesday, 16 July 2013 at 19:37:14 UTC, Gary Willoughby wrote:

 If however you remove the .byKey() call and use .keys instead, 
 it works!
With byKey, you are iterating over a range of original key values, meaning that attempting to remove any of them will result in bad bahavior. With .keys, you are iterating over a copied array of the keys, hence it's safe to remove them from the aa.
I find it disturbing that the built-in property "keys" would dup an entire array, and then copy all the keys into that array, whereas the function "byKeys()" will simply allow you to iterate on the keys. "keys" is in blatant violation of the "properties emulate members" mind-set.
Jul 17 2013
parent reply "Yota" <yotaxp thatGoogleMailThing.com> writes:
On Wednesday, 17 July 2013 at 09:48:06 UTC, monarch_dodra wrote:
 I find it disturbing that the built-in property "keys" would 
 dup an entire array, and then copy all the keys into that 
 array, whereas the function "byKeys()" will simply allow you to 
 iterate on the keys.

 "keys" is in blatant violation of the "properties emulate 
 members" mind-set.
My sentiments exactly. I feel it would also be more appropriate to name it 'getKeys'. I get the feeling that a lot of methods in Phobos use property just because they can, and it makes me itch when I come across them. 'dup' and 'idup' are big offenders. Can't wait to get a debugger that visualizes data, and tries to fetch both 'dup' properties of a multi-megabyte array. Of course there's no way to undo that now without breaking absolutely EVERYONE's code.
Jul 17 2013
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, July 17, 2013 19:21:03 Yota wrote:
 On Wednesday, 17 July 2013 at 09:48:06 UTC, monarch_dodra wrote:
 I find it disturbing that the built-in property "keys" would
 dup an entire array, and then copy all the keys into that
 array, whereas the function "byKeys()" will simply allow you to
 iterate on the keys.
 
 "keys" is in blatant violation of the "properties emulate
 members" mind-set.
My sentiments exactly. I feel it would also be more appropriate to name it 'getKeys'. I get the feeling that a lot of methods in Phobos use property just because they can, and it makes me itch when I come across them. 'dup' and 'idup' are big offenders. Can't wait to get a debugger that visualizes data, and tries to fetch both 'dup' properties of a multi-megabyte array. Of course there's no way to undo that now without breaking absolutely EVERYONE's code.
It should be noted that keys, dup, and idup are all built-in language features and have nothing to do with Phobos. They all pre-date property by a significant margin. The use of property in Phobos that's particularly stupid that I can think of off the top of my head is save for ranges. I don't know how Andrei ever thought that that made sense as a property rather than a normal function. But in general, I think that Phobos does a good job with property. It should also be noted that the line between property functions and normal functions is blurred by the fact that empty parens on a function call are optional. So, even if dup and idup were normal functions, they'd still probably get called all over the place without parens. At this point, assuming that the lack of parens means that something is a property is not a good idea. You pretty much have to go off of the names and what they do, in which case, unless the functions are badly named (like keys), it should be pretty obvious what is and isn't a property (at least in concept) in most cases. On a side note, I'd consider it a major misfeature for a debugger or IDE to assume that it can call property functions any more than it can call normal functions. Even if they shouldn't, they can have side-effects and do arbitrarily complex operations, since ultimately they're just normal functions. Not to mention, plenty of folks are likely to just not bother with property and just call their functions without parens. property's main value is likely to ultimately be in handling the corner cases where optional parens cause problems (like returning a delegate) and you want to treat the function as a property. It just won't matter for a lot of functions. - Jonathan M Davis
Jul 17 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/17/2013 10:21 AM, Yota wrote:

 On Wednesday, 17 July 2013 at 09:48:06 UTC, monarch_dodra wrote:
 I find it disturbing that the built-in property "keys" would dup an
 entire array, and then copy all the keys into that array, whereas the
 function "byKeys()" will simply allow you to iterate on the keys.

 "keys" is in blatant violation of the "properties emulate members"
 mind-set.
It is not a violation when the property is a value type, say, an int that is calculated by the property function. Otherwise, what to return when the value does not exist as a member?
 My sentiments exactly.  I feel it would also be more appropriate to name
 it 'getKeys'.
I think the "get" prefix is overused. Contrary to popular guidelines, if a function returns a value (property or not), it is acceptable and usually more useful when the function name is a noun: cpu.temperature; is more useful to me as opposed to cpu.getTemperature();
 'dup' and 'idup' are big offenders.
They are nothing compared to 'sort': :) Ali
Jul 17 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Gary Willoughby:

 Are associative arrays stable in D?
See also: http://d.puremagic.com/issues/show_bug.cgi?id=4179 Bye, bearophile
Jul 20 2013