Thread overview
[Issue 4279] New: AAs change key type
Aug 30, 2010
Andrej Mitrovic
Aug 30, 2010
Andrej Mitrovic
June 06, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4279

           Summary: AAs change key type
           Product: D
           Version: unspecified
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: druntime
        AssignedTo: sean@invisibleduck.org
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2010-06-06 04:54:52 PDT ---
With DMD v2.046 this program prints  const(char)[]  instead of  char[]


import std.stdio: writeln;
void main() {
    int[char[]] data = [cast(char[])"foo" : 1];
    foreach (key, val; data)
        writeln(typeid(typeof(key)));
}



Modifying AA keys after they are inserted in the AA is indeed bad because their hash value and position inside the AA doesn't get recomputed.

But the current design/behaviour is surprising and bad, because I have asked for a key type and the runtime/compiler gives me a different key type (forcing me to use casts). There are two possible behaviours that I see acceptable here:

1) to disallow AAs with mutable keys, their literals and definition too (as
Python does), so in this case this variable definition becomes a compile-time
error:
int[int[]] data;
2) or to allow mutable keys (and hope the programmer will not mutate them) (as
I think D1 does), and keep their type unchanged (mutable).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4279


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-08-29 21:07:55 PDT ---
As of 2.048, and according to my tests, DMD forces AA's to have a const type as the key type. For example:

import std.stdio: writeln;
void main()
{
    int[int[]] data;
    writeln(typeid(data));
}

Prints: int[const(int)[]]


And your AA literal key type gets converted to a const type as well:

import std.stdio: writeln;
void main()
{
    writeln(typeid([cast(char[])"foo" : 1]));
}

Prints: int[const(char)[]]

What happens here (if my interpretation is right), is that foo is first an array of immutable chars, it's casted to a mutable array of chars, and then DMD sees it is a key of an AA literal so it converts it to an array of const chars.

So DMD is most probably doing this:

On the left of assignment:
int[char[]] data
-> int[const(char)[]] data

On the right of assignment:
[cast(char[])const(char)[] : int]
-> int[cast(char[])const(char)[]]
-> int[char[]]
-> int[const(char)[]]

And the whole thing becomes:

int[const(char)[]] data = int[const(char)[]]


So if I got that right then DMD automatically changes the key type of an AA to be const, regardless of any casts. Having to change int[] to const(int)[] directly in the code would probably make the AA's harder to read, so maybe that's a good thing.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4279


Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy@yahoo.com


--- Comment #2 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-08-30 06:18:44 PDT ---
I think changing the key type to const during iteration is a useless gesture, and just serves as an annoyance rather than a guarantee.

See bug 4410 that I reported later but for a different reason.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4279



--- Comment #3 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-08-30 06:47:23 PDT ---
(In reply to comment #2)
> I think changing the key type to const during iteration is a useless gesture, and just serves as an annoyance rather than a guarantee.
> 
> See bug 4410 that I reported later but for a different reason.

In this case it doesn't change the key type during iteration, it changes it in the declaration:

import std.stdio: writeln;
void main()
{
    int[char[]] data = [cast(char[])"foo" : 1];
    writeln(typeid(data));
}

Prints: int[const(char)[]]

Unless I got it wrong here. :)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 30, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4279



--- Comment #4 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-08-30 06:57:47 PDT ---
Oh, I didn't notice that.

I was looking at bearophile's code.

But my point is the same -- converting to const does not guarantee anything. In reality, the only place where you are affected is during iteration, as everywhere else, the key is an input.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 28, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=4279


hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx


--- Comment #5 from hsteoh@quickfur.ath.cx 2012-02-27 17:34:23 PST ---
const handling in AA's is badly broken; see bug 7512.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------