DefaultDict{String, DataType}(SomeType)

using DataStructures

dd = DefaultDict{String, DataType}(Int32)
dd["i"] = Int32

Now, that’s OK:

julia> dd["i"]
Int32

And here I’d expect exactly the same value, just as default - however I get an error. Why?

julia> dd["default"]
ERROR: MethodError: no method matching Int32()
Closest candidates are:
  (::Type{T})(::AbstractChar) where T<:Union{Int32, Int64} at C:\Users\elk\AppData\Local\Programs\Julia\Julia-1.7.1\share\julia\base\char.jl:51
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at C:\Users\elk\AppData\Local\Programs\Julia\Julia-1.7.1\share\julia\base\char.jl:50
  (::Type{T})(::BigInt) where T<:Union{Int128, Int16, Int32, Int64, Int8} at C:\Users\elk\AppData\Local\Programs\Julia\Julia-1.7.1\share\julia\base\gmp.jl:357
  ...
Stacktrace:
 [1] (::DataStructures.var"#30#32"{DataStructures.DefaultDictBase{String, DataType, DataType, Dict{String, DataType}}})()
   @ DataStructures C:\Users\elk\.julia\packages\DataStructures\vSp4s\src\default_dict.jl:72
 [2] get!(default::DataStructures.var"#30#32"{DataStructures.DefaultDictBase{String, DataType, DataType, Dict{String, DataType}}}, h::Dict{String, DataType}, key::String)
   @ Base .\dict.jl:464
 [3] getindex
   @ C:\Users\elk\.julia\packages\DataStructures\vSp4s\src\default_dict.jl:71 [inlined]
 [4] getindex(a::DefaultDict{String, DataType, DataType}, args::String)
   @ DataStructures C:\Users\elk\.julia\packages\DataStructures\vSp4s\src\delegate.jl:21
 [5] top-level scope
   @ none:1

julia> 

With DefaultDict you can give a function as default “value”, see the manual. This causes a problem in your case because Int32 is a function-like thing you can call it as in Int32(1.0)) so DefaultDict treats it like a function.

I think that’s a problem with the DefaultDict API: it should not rely on the type of default “value” to decide what is a value and what is a function. This distinction should be made explicit in the API, for example with another constructor DefaultDict(; func=...). You might want to file an issue…

4 Likes

It should probably be noted that having a default value of Int32 is achievable with the current API as well:

julia> using DataStructures

julia> dd = DefaultDict{String, DataType}(()->Int32)
DefaultDict{String, DataType, var"#9#10"}()

julia> dd["default"]
Int32
4 Likes