Strong typed Dict{String, Int64} getindex(String) returns Any instead of Int64 value type?

If my Dict has a strong type defining it’s keys and values (and indeed it doesn’t let me add a different type), then why getindex from said Dict returns unstable Any?

julia> mydict = Dict([("A", 1), ("B", 2)])
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1

julia> mydictlookup(mykey) = mydict[mykey]
mydictlookup (generic function with 1 method)

julia> @code_warntype mydictlookup("A")
MethodInstance for mydictlookup(::String)
  from mydictlookup(mykey) in Main at REPL[74]:1
Arguments
  #self#::Core.Const(mydictlookup)
  mykey::String
Body::Any
1 ─ %1 = Base.getindex(Main.mydict, mykey)::Any
└──      return %1

It’s because mydict is a non-const global variable:

julia> mydict = Dict([("A", 1), ("B", 2)])
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1

julia> mydictlookup(mykey) = mydict[mykey]
mydictlookup (generic function with 1 method)

julia> mydictlookup("A")
1

julia> mydict = [1, 2]
2-element Vector{Int64}:
 1
 2

julia> mydictlookup("A")
ERROR: ArgumentError: invalid index: "A" of type String
Stacktrace:
 [1] to_index(i::String)
   @ Base ./indices.jl:300
 [2] to_index(A::Vector{Int64}, i::String)
   @ Base ./indices.jl:277
 [3] to_indices
   @ ./indices.jl:333 [inlined]
 [4] to_indices
   @ ./indices.jl:325 [inlined]
 [5] getindex(A::Vector{Int64}, I::String)
   @ Base ./abstractarray.jl:1170
 [6] mydictlookup(mykey::String)
   @ Main ./REPL[2]:1
 [7] top-level scope
   @ REPL[5]:1

julia> mydictlookup(1)
1

Ah so const was making all the difference!

julia> const mydict2 = Dict([("A", 1), ("B", 2)])
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1

julia> mydict2lookup(mykey) = mydict2[mykey]
mydict2lookup (generic function with 1 method)

julia> mydict2lookup("A")
1

julia> @code_warntype mydict2lookup("A")
MethodInstance for mydict2lookup(::String)
  from mydict2lookup(mykey) in Main at REPL[80]:1
Arguments
  #self#::Core.Const(mydict2lookup)
  mykey::String
Body::Int64
1 ─ %1 = Base.getindex(Main.mydict2, mykey)::Int64
└──      return %1
1 Like

https://docs.julialang.org/en/v1/manual/performance-tips/

1 Like