www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Associative arrays - non-intuitive 'in' semantics

reply Ben Davis <entheh cantab.net> writes:
Same example as in the other message:

Chunk[][char[4]] chunks;
chunks["DATA"]~=new Chunk();
if ("DATA" !in chunks) throw new Exception("No DATA chunk");

The exception is thrown. Changing it as follows fixes it:

if (cast(char[4])"DATA" !in chunks) throw new Exception("No DATA chunk");

I can sort of maybe see why this happens, but it is a bit unfortunate. 
As in, my guess is that it's for the same reason HashMap.get() in Java 
accepts Object instead of the key type: because you might want to pass a 
List when the HashMap contains ArrayLists, for example. But the number 
of times I've wanted to do that is far fewer than the number of times 
I've been stung by accidentally passing the wrong object. Should 'in' 
perhaps implicitly cast the LHS to the key type of the RHS?

Maybe best of both worlds is possible: the LHS is implicitly cast if an 
implicit conversion exists, but it's still allowed if not?

Discuss :)
Feb 17 2012
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
AA's seem to be full of bugs. You shouldn't be able to use a mutable
keytype. For now your best option is probably to just use string as
the key type.
Feb 17 2012
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 AA's seem to be full of bugs. You shouldn't be able to use a mutable
 keytype.
I agree: http://d.puremagic.com/issues/show_bug.cgi?id=6253 Bye, bearophile
Feb 17 2012
prev sibling next sibling parent Ben Davis <entheh cantab.net> writes:
On 18/02/2012 03:04, Andrej Mitrovic wrote:
 AA's seem to be full of bugs. You shouldn't be able to use a mutable
 keytype. For now your best option is probably to just use string as
 the key type.
The good news is I didn't intend for the key to be mutable. I've updated my code to make it explicitly immutable now. Besides, the bug bearophile showed us suggests that the compiler is already trying to const-ify the key implicitly (though probably not doing it correctly). The bad news is that the 'in' bug is separate - I've confirmed that now. It's when the key type is a fixed-length array/string, and an 'in' expression is used with a dynamic array/string. The example works if and only if I cast my string literals to fixed-length when I use an 'in' expression. No such cast is necessary when inserting an entry.
Feb 18 2012
prev sibling parent reply Ben Davis <entheh cantab.net> writes:
On 18/02/2012 03:04, Andrej Mitrovic wrote:
 AA's seem to be full of bugs. You shouldn't be able to use a mutable
 keytype. For now your best option is probably to just use string as
 the key type.
Another thought here actually: Static arrays have value semantics, so char[4] is no more mutable than int would be. So if I'm required to write Chunk[immutable(char[4])] then I should also be required to write Chunk[immutable(int)] which clearly isn't the case.
Feb 18 2012
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/18/12, Ben Davis <entheh cantab.net> wrote:
 Static arrays have value semantics
Bingo. I missed that. :)
Feb 18 2012
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Feb 18, 2012 at 04:04:36AM +0100, Andrej Mitrovic wrote:
 AA's seem to be full of bugs.
[...] Yeah, no kidding. The following code throws an error. int[dstring] map; foreach (key, val; map) { assert(map[key] == val); // throws AssertionError } Can you believe it? T -- War doesn't prove who's right, just who's left. -- BSD Games' Fortune
Feb 17 2012