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