On Wednesday, November 26, 2014 6:01:56 PM UTC-6, Test This wrote:
>
> I have the following function defined to check whether a record exists in 
> a Mongodb database (thanks a million for PyCall, which make it easy to use 
> pymongo 
> to interact with mongodb in julia).
>
> function doesrecexist(collectn::PyObject, rec::Dict{ASCIIString,Any})
>     # checks if record exists.
>     r = collectn[:find_one](rec)
>     return r
> end 
>
>
> If I define 
>
> rec = ["p" => 0.3] 
>
> julia recognizes it as Dict{ASCIIString, Float64}. Then if I do, 
>
> doesrecexist(collectn, rec), I get an error saying *ERROR: `doesrecexist` 
> has no method matching doesrecexist(::PyObject, 
> ::Dict{ASCIIString,Float64})*
>
> If I remove the type declaration for rec in doesrecexist, things work 
> fine. I have no other method defined for doesrecexist. Does it make sense 
> to get this error, given 
> that I intend to allow any values in the rec Dict by declaring Any? Is 
> there a workaround where I can declare the type for rec when defining the 
> function, without having 
> to define doesrecexist for Float values, Int values, String values etc.
>
> Thank you.
>

You've hit type invariance. In Julia, parametric types are invariant--that 
is, Dict{ASCIIString,Float64} is not a subtype of Dict{ASCIIString,Any}. 
However, you can use generic types instead:

function doesrecexist{T}(collectn::PyObject, rec::Dict{ASCIIString, T})
    ...
end

Which will match for all T. You can also restrict T to subtypes of a given 
type in the curly-braced section. For instance, if you wanted to guarantee 
that the type T was a subtype of Real:

function doesrecexist{T<:Real}(...)
    ...
end

For more information on why we use invariant parametric types, search the 
list for "parametric invariant" or similar; there have been a few 
discussions on the topic.

Patrick

Reply via email to