Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AA] AAs change key type #17226

Open
dlangBugzillaToGithub opened this issue Jun 6, 2010 · 5 comments
Open

[AA] AAs change key type #17226

dlangBugzillaToGithub opened this issue Jun 6, 2010 · 5 comments
Labels
Arch:x86 Issues specific to x86 Druntime:AA Specific to Associative Arrays Druntime Specific to druntime OS:Windows P3 Severity:normal

Comments

@dlangBugzillaToGithub
Copy link

bearophile_hugs reported this on 2010-06-06T04:54:52Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=4279

CC List

Description

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).
@dlangBugzillaToGithub
Copy link
Author

andrej.mitrovich (@AndrejMitrovic) commented on 2010-08-29T21:07:55Z

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.

@dlangBugzillaToGithub
Copy link
Author

schveiguy (@schveiguy) commented on 2010-08-30T06:18:44Z

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.

@dlangBugzillaToGithub
Copy link
Author

andrej.mitrovich (@AndrejMitrovic) commented on 2010-08-30T06:47:23Z

(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. :)

@dlangBugzillaToGithub
Copy link
Author

schveiguy (@schveiguy) commented on 2010-08-30T06:57:47Z

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.

@dlangBugzillaToGithub
Copy link
Author

hsteoh commented on 2012-02-27T17:34:23Z

const handling in AA's is badly broken; see bug 7512.

@thewilsonator thewilsonator added Druntime Specific to druntime Druntime:AA Specific to Associative Arrays labels Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arch:x86 Issues specific to x86 Druntime:AA Specific to Associative Arrays Druntime Specific to druntime OS:Windows P3 Severity:normal
Projects
None yet
Development

No branches or pull requests

2 participants