The manual says Type{xxx} matches only the object xxx, but it does not seem
to be true. Maybe this is related to my post yesterday "Reflection bug for
parameterized types?" because this could be another case of confusion
between the TypeVars declared in a parameterized type declaration and
TypeVars used to instantiate a parameterized type.
Here is an example, run in Julia 0.3:
julia> begin
f{t,n}(::Type{Array{t}}, ::Array{t,n}) = (t,n,1)
f{t,n}(::Type{Array{t,n}}, ::Array{t,n}) = (t,n,2)
end
julia> methods(f)
# 2 methods for generic function "f":
f{t,n}(::Type{Array{t,n}},::Array{t,n}) at none:3
f{t,n}(::Type{Array{t,N}},::Array{t,n}) at none:2
julia> f(Array{Int,1}, [1,2,3])
(Int32,1,2)
julia> f(Array{Int}, [1,2,3])
(Int32,1,2) *# I was expecting (Int32,1,1) !*
julia> Array{Int} == Array{Int,1}
false
So Type{Array{t,n}} with t=Int and n=1 matches Array{Int} even though
Array{Int,1} and Array{Int} are not the same object!
This only happens when the methods have more than one argument and there
are static parameters shared between the Type{...} argument and another
argument. Otherwise Type{Array{t}} only matches Array with only one
parameter specified, as expected.
The first method appears to be unreachable. This means, for example, that
the predefined method convert{T,n,S}(::Type{Array{T}}, x::Array{S,n}) in
base/array.jl can never be called; convert{T,n,S}(::Type{Array{T,n}},
x::Array{S,n}) will be called instead. It doesn't appear that anything
breaks because of that, but clearly method dispatch is not working the way
the author of that code expected.
I didn't search for a pre-existing bug about this, because it's kind of
hard to search when the only search key you have is a generic word like
"type."
Should I file a bug for this? Or is it supposed to behave like this and
the manual is just wrong?