What's the expected behaviour when using vector as dict(hash) key?

a,k=Dict(),[1]
a[k]=1
k[1]=2
print(a," ",a[k]," ");print(a[[1]]," ");println(a[[2]]);
a[k]=2
print(a," ",a[k]," ");print(a[[1]]," ");println(a[[2]]);

What should we expect? Or should we completely forbids using vectors(arrays) as key? Then why does hash for array relies on value rather than objectid?

Arrays compare equality by their contents, thus they hash by their (current) contents. If you change the contents of an array that’s being used as a dictionary key, you’ll no longer be able to find it in the dictionary. This is the expected behavior, and I think we have it documented… if not let’s add it as a warning to the documentation.

1 Like

However when using Dict in callback functions, and of course we can’t require the caller to ensure it doesn’t reuse any arrays, disaster comes about. Is this still by design?

Assuming that the keys are immutable is pretty common, I think. You could submit a PR to Base that adds an

index = isimmutable(index) ? index : copy(index)

to base/dict.jl setindex! methods and see what people think. Or create a MutableKeyDicts package.

1 Like

I agree. From personal perspect I’d prefer adding MutableKeyDicts, and forbids mutable keys in Dict. Hope no one has opened a similar issue.

If you want to hash based on object-id, then you can use the built-in IdDict type:

d = IdDict()
k = [23]
d[k] = "yes"
k2 = [23]
d[k2] # throws exception
get(d, k2, "no") # returns "no"
k[1] = 17
d[k] # returns "yes"

This is probably the behavior you want if you are using arrays as keys (and is also much faster than hashing the array contents).

9 Likes