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

Lutger Blijdestijn lutger.blijdestijn at gmail.com
Sat Nov 20 02:46:56 PST 2010


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.
> 
> 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?
> 
> Andrei

What I don' t understand is why it is allowed to use mutable types where the 
key type is immutable. This way you can get immutable references to mutable 
data back without explicit casting (via the .keys property for example). The 
example would not compile if this wasn't allowed.


More information about the Digitalmars-d mailing list