On 2010-11-20 03:07:57 -0500, Andrei Alexandrescu <seewebsiteforem...@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.for...@michelf.com
http://michelf.com/

Reply via email to