On 20-nov-10, at 09:07, Andrei Alexandrescu wrote:

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.

I think that you basically stated the important rules: lookup, update should use const(char[]), set (i.e. potentially add a new key) immutable(char[]).


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?

I would consider the first program as written invalid (at runtime) because the initial value is not set, so you cannot update it with ++.
Also potential hidden idup should not be added IMHO.
I don't find the second program so bad...

Fawzi

Reply via email to