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

Fawzi Mohamed fawzi at gmx.ch
Sat Nov 20 03:42:32 PST 2010


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



More information about the Digitalmars-d mailing list