www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - TDPL dictionary example - ERROR with dmd and gdc

reply Caligo <iteronvexor gmail.com> writes:
I've been following the examples in the book and on page 8 we have this:

import std.stdio;
import std.string;

void main(){

     size_t[string] dictionary;
    foreach(line; stdin.byLine()){
              foreach(word; splitter(strip(line))){
                          if(word in dictionary) continue;
                    auto newID = dictionary.length;
                          dictionary[word] = newID;
                    writeln(newID, '\t', word);
            }
    }
}

With the latest GDC, which I think uses the latest 2.051, I get this error:
dictionary.d:12: Error: associative arrays can only be assigned values with
immutable keys, not char[]

Someone told me on digitalmars-d.learn that it works with DMD, but I just
downloaded the latest DMD that was just released and I still get the same
error.

Is there a workaround to this? and why the error?
Dec 24 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/2010 11:35 AM, Caligo wrote:
 I've been following the examples in the book and on page 8 we have this:

 import std.stdio;
 import std.string;

 void main(){

       size_t[string] dictionary;
      foreach(line; stdin.byLine()){
                foreach(word; splitter(strip(line))){
                            if(word in dictionary) continue;
                      auto newID = dictionary.length;
                            dictionary[word] = newID;
                      writeln(newID, '\t', word);
              }
      }
 }

 With the latest GDC, which I think uses the latest 2.051, I get this error:
 dictionary.d:12: Error: associative arrays can only be assigned values
 with immutable keys, not char[]

 Someone told me on digitalmars-d.learn that it works with DMD, but I
 just downloaded the latest DMD that was just released and I still get
 the same error.

 Is there a workaround to this? and why the error?
Yah, this has been a long-standing issue. dmd has accepted for a while the code but produced incorrect results. Since then the bug has been fixed to refuse compilation. The problem is, line has type char[] and the map's key type is string, i.s. array of immutable char. To convert x to string you need to say either x.idup or to!string(x). In theory the compiler/library would be clever enough to do that automatically when necessary, but we decided against it for now. So: replace dictionary[word] with either dictionary[word.idup] or dictionary[to!string(word)]. A future printing will correct this mistake. Andrei
Dec 24 2010
parent reply Caligo <iteronvexor gmail.com> writes:
ok, thanks.  And just a reminder that there is nothing about this on the
errata.



On Fri, Dec 24, 2010 at 11:51 AM, Andrei Alexandrescu <
SeeWebsiteForEmail erdani.org> wrote:

 On 12/24/2010 11:35 AM, Caligo wrote:

 I've been following the examples in the book and on page 8 we have this:

 import std.stdio;
 import std.string;

 void main(){

      size_t[string] dictionary;
     foreach(line; stdin.byLine()){
               foreach(word; splitter(strip(line))){
                           if(word in dictionary) continue;
                     auto newID = dictionary.length;
                           dictionary[word] = newID;
                     writeln(newID, '\t', word);
             }
     }
 }

 With the latest GDC, which I think uses the latest 2.051, I get this
 error:
 dictionary.d:12: Error: associative arrays can only be assigned values
 with immutable keys, not char[]

 Someone told me on digitalmars-d.learn that it works with DMD, but I
 just downloaded the latest DMD that was just released and I still get
 the same error.

 Is there a workaround to this? and why the error?
Yah, this has been a long-standing issue. dmd has accepted for a while the code but produced incorrect results. Since then the bug has been fixed to refuse compilation. The problem is, line has type char[] and the map's key type is string, i.s. array of immutable char. To convert x to string you need to say either x.idup or to!string(x). In theory the compiler/library would be clever enough to do that automatically when necessary, but we decided against it for now. So: replace dictionary[word] with either dictionary[word.idup] or dictionary[to!string(word)]. A future printing will correct this mistake. Andrei
Dec 24 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/2010 12:35 PM, Caligo wrote:
 ok, thanks.  And just a reminder that there is nothing about this on the
 errata.
Fixed: http://www.erdani.com/tdpl/errata/ Thanks! Andrei
Dec 24 2010