Why does this conversion happen implicitly?

julia> d = Dict{String,Vector{Int}}()
Dict{String,Array{Int64,1}}()

julia> v = view(zeros(Int, 10), :)
10-element view(::Array{Int64,1}, :) with eltype Int64:
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0

julia> d["as"] = v

julia> d["as"]
10-element Array{Int64,1}:
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0

I tripped up today because I had set the wrong values type on my dictionary, so some views were implicitly getting copied upon assignment. Why does this happen? And I don’t mean why in terms of code machinery, but why was it designed this way? I feel like the dict setindex method should accept right hand sides that are strict subtypes of the key type, rather than converting - conversion should be decided explicitly by the user.

Consider:

julia> d = Dict{String,Float64}()
Dict{String,Float64} with 0 entries

julia> d["foo"] = 123
123

julia> d
Dict{String,Float64} with 1 entry:
  "foo" => 123.0

People love the convenience of this. Automatic conversion when values are assigned to typed locations is one of the things that makes Julia feel like a scripting language rather a fussy static language where types have to match exactly or an error gets thrown. You’ve almost certainly relied on this far more often than you realize. It is potentially problematic, however, when it ends up converting and therefore copying mutable values like arrays.

3 Likes

You meant

d["as"] = v

right?

1 Like

view creates a SubArray and SubArray is not a subtype of Array. There are no subtypes of concrete types in Julia.

3 Likes

My bad - I accidently ommited the key line! Corrected original post.

Exactly. I had initially expected this to error, because SubArray is not a subtype of Array, but instead Dict converts both the key and value types (see for example https://github.com/JuliaLang/julia/blob/master/base/dict.jl#L381).

Thanks Stefan - this implicit behaviour isn’t entirely to my taste, but I understand why it can be nice in some cases.