On August 23, 2015 at 21:08:16, Kevin Squire (kevin.squ...@gmail.com) wrote:
If the type hierarchy is implemented well, functions for `Dict` would ideally 
be written to work with `super(Dict)` (i.e., `Associative`).  And in fact, some 
are--e.g., `in`, `haskey`, `show`, `keys`, `values`, etc.  See `base/dict.jl` 
for the implementation.

This had actually occurred to me when I was first considering how one might 
implement variations on `Dict`. I think it’s somewhat natural when writing a 
function that deals with integers to used `myfn(foo::Int)` instead of 
`myfn(foo::Int64)`, but without digging into the innards of dict.jl I wouldn’t 
have thought to write `myfn(foodict::Associative)` instead of 
`myfn(foodict::Dict)`.

I opened https://github.com/JuliaLang/julia/issues/12774 to gather any 
discussion/opinions around adding a warning to help out making sure that 
library code is written as generally as possible.

To work around that, the implementation of `DefaultDict` (and other dictionary 
types) in `DataStructures.jl` wraps a `Dict` (as in your implementation), and 
uses a `@delegate` macro to delegate function calls to the wrapped `Dict`.  
This has been copied a few other places, but it's hard to say this is the best 
or most Julian way to do this.  

Thanks for the pointer! This is an interesting solution…it seems that sometimes 
Julia recycles OOP patterns, sometimes it goes more in the direction of 
ML-style type algebra, but here we have good ol’ LISP macros. This certainly 
should work for extending standard-library behavior, but still doesn’t do much 
for third-party libs (though assuming they properly specialize on abstract 
types, it shouldn’t be an issue).

I am still a bit confused about:

    > 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…)

After all, I’ve defined `DefaultDict` as a subtype of `Associative`. Here I’m 
being given a method error, but the suggested “closest candidate” has 
`Associative` in the signature. Reading the actual implementation of 
`setindex!` it’s clear why this method won’t work for my `DefaultDict`, but the 
error message is more than a bit confusing.

Actually (and this may be getting a bit off-in-the-weeds, but…), it seems to me 
that the signature for `setindex!` is wrong. Yes, it’s been defined with that 
signature, but type inference on the method body would reveal that this method 
in fact *cannot* accept any `Associative`.

Reply via email to