IMHO, there are two things missing:
1) You should define outer constructor for `DefaultDict(val, Dict())`;
2) You should make your promotion rules parametric.


On Sunday, August 23, 2015 at 7:48:11 PM UTC+2, Joshua Ballanco wrote:
>
> 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
>

Reply via email to