Principled method of lookup-or-insert in associative arrays?

Michel Fortin michel.fortin at michelf.com
Sat Nov 20 04:39:11 PST 2010


On 2010-11-20 03:07:57 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail at erdani.org> said:

> TDPL has an example that can be reduced as follows:
> 
> void main() {
>    uint[string] map;
>    foreach (line; stdin.byLine()) {
>      ++map[line];
>    }
> }
> 
> byLine reuses its buffer so it exposes it as char[]. Therefore, 
> attempting to use map[line] will fail. The program compiled and did the 
> wrong thing because of a bug.
> 
> The challenge is devising a means to make the program compile and work 
> as expected. Looking up an uint[string] with a char[] should work, and 
> if the char[] is to be inserted, a copy should be made (via .idup or 
> to!string). The rule needs to be well defined and reasonably general.
> 
> The effect is something like this:
> 
> void main() {
>    uint[string] map;
>    foreach (line; stdin.byLine()) {
>      auto p = line in map;
>      if (p) ++*p;
>      else map[line.idup] = 1;
>    }
> }
> 
> Ideally the programmer would write the simple code (first snippet) and 
> achieve the semantics of the more complex code (second snippet). Any 
> ideas?

But didn't you agree with me yesterday in another thread that it's best 
to make the caller responsible for the idup in cases where you need a 
string to be immutable? Now you want the reverse for AAs?

Consider this example:

	uint[string][100] maps;
	foreach (line; stdin.byLine()) {
		foreach (map; maps) {
			++map[line];
		}
	}

With your proposal, you'd be silently iduping 100 times each line to 
produce 100 times the same immutable string.

It's true that it's difficult to make the caller responsible for 
iduping the string since whether you need a true immutable string or 
not depends on a test, but I'm still wary about functions that idup 
things on your behalf.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list