# Unexpected subtyping behavior \<:

**URL:** https://discourse.julialang.org/t/unexpected-subtyping-behavior/31701
**Category:** General Usage
**Tags:** type
**Created:** [November 30, 2019, 8:05pm UTC](https://discourse.julialang.org/t/unexpected-subtyping-behavior/31701 "2019-11-30T20:05:58Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![holylorenzo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/holylorenzo/32/34169_2.png) [@holylorenzo](https://discourse.julialang.org/u/holylorenzo)
#### Post date: [November 30, 2019, 8:05pm UTC](https://discourse.julialang.org/t/unexpected-subtyping-behavior/31701/1 "2019-11-30T20:05:58Z")

</div>

Hey everyone, could someone explain this subtyping behavior to me?  
It does not seem intuitive to me.

```julia
Array{T where T} <: AbstractArray{T where T} # true
Array{Array{T where T}} <: AbstractArray{Array{T where T}} # also true

Array{Array{T where T}} <: AbstractArray{AbstractArray{T where T}} # false

```

I’m wondering why the last expression evaluates to false.

Thanks in advance!

---

<div class="post-metadata">

### Author: ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)
#### Post date: [November 30, 2019, 8:08pm UTC](https://discourse.julialang.org/t/unexpected-subtyping-behavior/31701/2 "2019-11-30T20:08:08Z")

</div>

> [@Array{T, 1} where T\<:Real versus Array{T where T\<:Real, 1}](https://discourse.julialang.org/t/array-t-1-where-t-real-versus-array-t-where-t-real-1/31249):
>
> T1 = Array{T, 1} where T\<:Real represents all possible arrays of the form [T, T, T, T, . . .], i.e., any array of T1 consists of elements of the subtype of Real and they have to be of same type. On the other hand, T2 = Array{T where T\<:Real, 1} represents all possible arrays of the form [T, T', T'', T''', ...]. So any array of T2 consists of elements of subtypes of Real but they could be of different types to each other. Therefore I feel it is obvious that T2 can represent broader range of v…

---

<div class="post-metadata">

### Author: ![bashonubuntu](https://avatars.discourse-cdn.com/v4/letter/b/f19dbf/32.png) [@bashonubuntu](https://discourse.julialang.org/u/bashonubuntu)
#### Post date: [November 30, 2019, 8:58pm UTC](https://discourse.julialang.org/t/unexpected-subtyping-behavior/31701/3 "2019-11-30T20:58:17Z")

</div>

To elaborate a bit more, if` x <: y` then in general `Point{x} <: Point{y}` may not always be true.

To begin, your first and second example work because `Array <: AbstractArray` and what you are passing inside `{}` are exactly the same i.e. in the second example, you are declaring `x = Array{T where T}` and `y = Array{T where T}` and then checking if ` Array{x} <: AbstractArray{y}` is true. However, since `x = y` this is equivalent to checking if `Array{x} <: AbstractArray{x}` is true, which it is since `Array <: AbstractArray`. Similarly, for the first example. The first and second examples basically say that any `Array` can be represented as an `AbstractArray.`

```julia
julia> Array{Float64} <: AbstractArray{Float64}
true

```

Note that what you’ve done in your first and second examples is completely different from the following  
because you are passing exactly the same types (unlike, subtypes which are passed below) inside `{}`.

```julia
julia> Float64 <: Real
true

julia> Array{Float64} <: AbstractArray{Real}
false

julia> Array{Float64} <: Array{Real}
false

```

Now, as may be apparent from the previous example, the behavior manifested by the first and second examples need not hold if what you are passing inside `{}` changes as it does in the third example. In fact, the third expression won’t even evaluate to true if I set `Point = Array` on both sides of the equation i.e.

```julia
julia> Array{T where T} <: AbstractArray{T where T}
true

julia> Array{Array{T where T}} <: Array{AbstractArray{T where T}}
false

```

This behavior is consistent with the documentation below.  
[https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Types-1](https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Types-1)

Here is a more formal treatment of what’s meant by covariant, contravariant and invariant subtyping

[https://eli.thegreenplace.net/2018/covariance-and-contravariance-in-subtyping/](https://eli.thegreenplace.net/2018/covariance-and-contravariance-in-subtyping/)
