# Incorrect concrete type for Vector{Pair{Any, Any}}?

Hello,

My question’s rather simple:

``````julia> [1=>2]
1-element Vector{Pair{Int64, Int64}}:
1 => 2

julia> [1=>2] isa Vector{Pair{Any, Any}}
false
``````

Why is `Vector{Pair{Int64, Int64}}` not a subtype of `Vector{Pair{Any, Any}}`?

And if useful, here is my Julia version:

``````julia> versioninfo()
Julia Version 1.6.4
Commit 35f0c911f4 (2021-11-19 03:54 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-11.0.1 (ORCJIT, skylake)
Environment:
JULIA_DEPOT_PATH = /home/andreinicusan/Prog/Julia/builds/julia-1.6.4/packages:

``````

Thanks,
Leonard

I don’t know the why but

julia> [1=>2] isa Vector{Pair{T,T}} where T <: Any
true

Yes, this is correct and expected behaviour. `Vector{Pair{Any, Any}}` is a concrete type that can be instantiated, it would be a vector of pairs of different types. Concrete types cannot have subtypes, therefore `Vector{Pair{Int, Int}}` cannot be its subtype.

In particular, you can find this warning in the docs:

This last point is very important: even though `Float64 <: Real` we DO NOT have `Point{Float64} <: Point{Real}` .

An alternative convenient test could be

``````1.7.0> [1=>2] isa Vector{<:Pair}
true
``````
6 Likes

Thank you for the very quick replies. It seems odd that `Tuple` is covariant, while `Pair` is invariant; I understand that covariance is special-cased, but why isn’t a type as fundamental as `Pair` - not unlike `Tuple` - made covariant?

I am currently working with a library that asserts types with `constraints::Vector{Pair{Any,Any}}`, so I need to enforce the `Any` quite awkwardly:

``````julia> [1=>2, ""=>""][1:end-1]
1-element Vector{Pair{Any, Any}}:
1 => 2

``````

A type like `Vector` cannot really be covariant: one cannot pass e.g. `Vector{Int}` everywhere where `Vector{Any}` is expected. This function would fail if you could pass `Vector{Int}` to it:

``````f(x::Vector{Any}) = push!(x, "abc")
``````

but it works for `Vector{Any}`.

If you do need to create a `Vector{Pair{Any, Any}}` containing pairs of a single type (do you really need it?), it’s possible much less awkwardly: `Pair{Any, Any}[1 => 2]`.

3 Likes

Apparently, `Tuple` is abstract unless its parameters are concrete, so you cannot instantiate it. I am not sure if that makes it contravariant or not, but at least there is nothing preventing it to have subtypes.

Yes, or, alternatively:

``````[Pair{Any, Any}(1,2)]
``````

This is a common idiom in Julia, btw, for any type, `T`, you can create a `Vector{T}` by writing `T[...]`

That is terrible, BTW. Maybe you can open an issue/PR to have it changed. This is really not idiomatic Julia.

1 Like

it might not be bad. sometimes this is what you need to prevent ridiculous amounts of compiler specialization. that said, 90% of the time, this is bad.