# Subtyping Conventions for Dicts are Unexpected

**URL:** <https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040>\
**Category:** General Usage\
**Created:** [January 6, 2020, 8:15pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040 "2020-01-06T20:15:50Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)\
**Post date:** [January 6, 2020, 8:15pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/1 "2020-01-06T20:15:50Z")

</div>

If

```julia
Int64 <: Real

```

is true, and I presume Julia follows normal function typing rules (for dicts) where the “return” type can be more specific than indicated by the type annotation, why isn’t the following true?

```julia
 Dict(:x=>[1,2], :y=>[1,2]) isa Dict{Symbol, Array{<:Real, 1}}

```

Do I need to do something like:

```julia
Dict(:x=>[1,2], :y=>[1,2]) isa <:Dict{Symbol, Array{Real, 1}}

```

to ‘ask the question’ properly?

---

<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:** [January 6, 2020, 8:30pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/2 "2020-01-06T20:30:50Z")

</div>

Welcome!

In Julia, type parameters are invariant. So even though `Int <: Real` it is _not true_ that `Array{Int} <: Array{Real}`.Your use-case is just another example of such type invariance.

```julia
julia> Int <: Real
true

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

```

You can read more about types here

[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)

---

<div class="post-metadata">

**Author:** ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)\
**Post date:** [January 6, 2020, 8:52pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/3 "2020-01-06T20:52:35Z")

</div>

What is happening here?

```julia
julia> [1,2] isa Array{<:Real,1}
true

```

and here?

```julia
julia> Array{Int} <: Array{<:Real}
true

```

---

<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:** [January 6, 2020, 9:16pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/4 "2020-01-06T21:16:09Z")

</div>

Your last piece of code is equivalent to checking

```julia
julia> Array{Int} <: Array{T} where {T <: Real}
true

```

The RHS is the set of all types of the form `Array{T} where {T<:Real}`. So, an element that belongs to `Array{Int}` is also an element of `Array{T} where {T<:Real}`. An element that belongs to `Array{Float64}` is also an element of `Array{T} where {T<:Real}` and so on

```julia
julia> Array{Float64} <: Array{T} where {T <: Real}
true

```

---

<div class="post-metadata">

**Author:** ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)\
**Post date:** [January 6, 2020, 9:21pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/5 "2020-01-06T21:21:30Z")

</div>

So it seems like I can get the kind of type variance behavior that I intuitively want to use – returning to the original question, why doesn’t this “hack” work for the more complex type? :

```julia
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{<:Real, 1}}
false

```

---

<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:** [January 6, 2020, 9:22pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/6 "2020-01-06T21:22:48Z")

</div>

You need

```julia
julia> Dict{Symbol, Array{Int,1}} <: Dict{R, Array{T, 1}} where {R, T}
true

```

---

<div class="post-metadata">

**Author:** ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)\
**Post date:** [January 6, 2020, 9:24pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/7 "2020-01-06T21:24:21Z")

</div>

Thanks!  
I see that

```julia
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true

```

also works.

Is the way I am doing this not the “Julian” way to do things?

---

<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:** [January 6, 2020, 9:30pm UTC](https://discourse.julialang.org/t/subtyping-conventions-for-dicts-are-unexpected/33040/8 "2020-01-06T21:30:08Z")

</div>

This is also fine and depends on whether you want to use a fixed type or its subset. What I wrote is slightly more generic because you can replace `R` with any subtype of `Symbol.` This is what you are doing with `Array{T, 1} where {T<:Real}` as well. You are allowing the code to compile for a subtype of `Real` so you have flexibility in that you can pass a subtype of `Real` in place of `T` like so

```julia
julia> Dict{Symbol, Array{Int,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true

julia> Dict{Symbol, Array{Float64,1}} <: Dict{Symbol, Array{T, 1}} where {T <: Real}
true

```

There is nothing non-Julian in what you did but I like to keep my code as generic as possible 🙂 Notice that keeping the code like `Array{T, 1} where {T<:Real}` has no runtime penalty.
