Hello all,
Apologies in advance if I’m missing something obvious. I’ve only just started
experimenting with some of the more advanced features of Julia’s types, and
I’ve hit a bit of a wall…
Say I wanted to replicate something like Python’s `collections.defaultdict` or
Ruby’s `Hash` class with a default value. So far this is what I have:
——8<——8<——
immutable DefaultDict{K, V} <: Associative{K, V}
default::V
dict::Dict{K, V}
end
function DefaultDict(val)
return DefaultDict(val, Dict())
end
function Base.getindex{K, V}(dd::DefaultDict{K, V}, key::K)
if haskey(dd.dict, key)
getindex(dd.dict, key)
else
dd.default
end
end
——8<——8<——
Ideally, I’d like to avoid having to re-implement all of the methods one would
expect `Dict` to work with, since I can trivially convert from a `DefaultDict`:
——8<——8<——
Base.convert(::Type{Associative}, dd::DefaultDict) = dd.dict
Base.promote_rule(::Type{Associative}, ::Type{DefaultDict}) = Associative
——8<——8<——
However, this doesn’t seem to work as I had hoped it might:
——8<——8<——
> foo = DefaultDict(42)
> foo['a'] = 1
ERROR: MethodError: `setindex!` has no method matching
setindex!(::DefaultDict{Any,Any}, ::Int64, ::Char)
Closest candidates are:
setindex!(::Associative{K,V}, ::Any, ::Any, ::Any, ::Any…)
——8<——8<——
Sure, implementing `setindex!`, `length`, `start`, etc. would be trivial, but
I’m more worried about third-party code that expects `Dict` arguments. In
principle I’d like to still be able to pass instances of `DefaultDict` to
methods that would otherwise expect `Dict`s.
Am I completely off-base with this approach? What’s the most “Julian” solution
to specializing types in this manner?
Cheers,
Josh