I defined the following merge
function for a custom Dict
type:
struct MixedKeyDict{T<:Tuple} #<: AbstractDict{Any,Any}
dicts::T
end
Base.merge(f::Function, d::MixedKeyDict, others::MixedKeyDict...) = _merge(f, (), d.dicts, (d->d.dicts).(others)...)
Base.merge(f, d::MixedKeyDict, others::MixedKeyDict...) = _merge(f, (), d.dicts, (d->d.dicts).(others)...)
function _merge(f, res, d, others...)
ofsametype, remaining = _alloftype(Base.heads(d), ((),), others...)
return _merge(f, (res..., merge(f, ofsametype...)), Base.tail(d), remaining...)
end
_merge(f, res, ::Tuple{}, others...) = _merge(f, res, others...)
_merge(f, res, d) = MixedKeyDict((res..., d...))
_merge(f, res, ::Tuple{}) = MixedKeyDict(res)
function _alloftype(ofdesiredtype::Tuple{Vararg{D}}, accumulated, d::Tuple{D,Vararg}, others...) where D
return _alloftype((ofdesiredtype..., first(d)),
(Base.front(accumulated)..., (last(accumulated)..., Base.tail(d)...), ()),
others...)
end
function _alloftype(ofdesiredtype, accumulated, d, others...)
return _alloftype(ofdesiredtype,
(Base.front(accumulated)..., (last(accumulated)..., first(d))),
Base.tail(d), others...)
end
function _alloftype(ofdesiredtype, accumulated, ::Tuple{}, others...)
return _alloftype(ofdesiredtype,
(accumulated..., ()),
others...)
end
_alloftype(ofdesiredtype, accumulated) = ofdesiredtype, Base.front(accumulated)
For two dicts, this works perfectly well:
julia> d = MixedKeyDict((Dict(1=>3),Dict(4. => 2)))
MixedKeyDict{Tuple{Dict{Int64,Int64},Dict{Float64,Int64}}} with 2 entries:
1 => 3
4.0 => 2
julia> e = MixedKeyDict((Dict(1=>7),Dict(5. => 9)))
MixedKeyDict{Tuple{Dict{Int64,Int64},Dict{Float64,Int64}}} with 2 entries:
1 => 7
5.0 => 9
julia> merge(+, d, e)
MixedKeyDict{Tuple{Dict{Int64,Int64},Dict{Float64,Int64}}} with 3 entries:
1 => 10
4.0 => 2
5.0 => 9
But as soon as I add another one, Julia gets completely stuck and I have to kill the whole process.
julia> f = MixedKeyDict((Dict(2=>7),Dict(5. => 9)))
MixedKeyDict{Tuple{Dict{Int64,Int64},Dict{Float64,Int64}}} with 2 entries:
2 => 7
5.0 => 9
julia> merge(+, d, e, f) #gets stuck
I thought there might be a bug in my code, so I tried debugging it with Debugger.jl
, but the weird part is,that it works just fine if I just @enter
the function and let it continue without any breakpoints set:
julia> using Debugger
julia> @enter merge(+, d, e, f)
In merge(f, d, others) at /home/simeon/Documents/Julia/TypeStableDicts/src/TypeStableDicts.jl:33
>33 Base.merge(f::Function, d::MixedKeyDict, others::MixedKeyDict...) = _merge(f, (), d.dicts, (d->d.dicts).(others)...)
About to run: (getproperty)(<suppressed 71 bytes of output>, :dicts)
1|debug> c
MixedKeyDict{Tuple{Dict{Int64,Int64},Dict{Float64,Int64}}} with 4 entries:
2 => 7
1 => 10
4.0 => 2
5.0 => 18
If I tell Debugger.jl
to use the compiled mode, it gets stuck again. This seems to be a bug in the compiler. Is this a known bug – should I open an issue? Are there any workarounds for this to work?
My Julia version:
julia> versioninfo()
Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
I’ve also tried it with the latest nightly, but no luck there either.