# Broader (non-concrete) types in NamedTuple

**URL:** <https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [October 11, 2018, 2:01pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183 "2018-10-11T14:01:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 11, 2018, 2:01pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/1 "2018-10-11T14:01:57Z")

</div>

I wonder if constructing `NamedTuple{names, T}(::S)` where `S <: T` is a bug, eg

```julia
julia> VERSION
v"1.1.0-DEV.439"

julia> NamedTuple{(:a, :b)}((missing, 10))
(a = missing, b = 10)

julia> NamedTuple{(:a, :b),Tuple{Union{Missing, Float32},Union{Missing, Int16}}}((missing, 10))
NamedTuple{(:a, :b),Tuple{Union{Missing, Float32},Union{Missing, Int16}}}((missing, 10))

```

---

<div class="post-metadata">

**Author:** ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)\
**Post date:** [October 11, 2018, 4:03pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/2 "2018-10-11T16:03:11Z")

</div>

Why would it be a bug? Both the NamedTuples you constructed are valid NamedTuples.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 11, 2018, 4:32pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/3 "2018-10-11T16:32:19Z")

</div>

Cf

```julia
julia> Tuple{Union{Missing, Float32},Union{Missing, Int16}}((missing, 10))
(missing, 10)

julia> typeof(ans)
Tuple{Missing,Int16}

```

so you cannot do this with `Tuple`.

If you think of a `NamedTuple` as a container implemented using a `Tuple`, then this is OK, but if you think of it as “a `Tuple` with names” then this is inconsistent.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [October 11, 2018, 4:34pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/4 "2018-10-11T16:34:09Z")

</div>

Related: NamedTuples are apparently not covariant:

```julia
julia> NamedTuple{(:a,), Tuple{Int}} <: NamedTuple{(:a,), Tuple{Integer}}
false

julia> Tuple{Int} <: Tuple{Integer}
true

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 12, 2018, 9:40am UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/6 "2018-10-12T09:40:31Z")

</div>

Looking at the source, it seems that having broader types for the fields is something that is [allowed](https://github.com/JuliaLang/julia/blob/e11b0b0780255a02d9ea55c549e9a562e04dcf83/base/namedtuple.jl#L128), at least `Base.show` takes special care when printing.

@jeff.bezanson, since you wrote most of this, can you please clarify the intention?

also @cstjean’s point about lack of covariance and whether this is intended.

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [October 12, 2018, 2:23pm UTC](https://discourse.julialang.org/t/broader-non-concrete-types-in-namedtuple/16183/7 "2018-10-12T14:23:23Z")

</div>

It’s not clear whether NamedTuples (or, indeed, tuples! see [https://github.com/JuliaLang/julia/issues/24614](https://github.com/JuliaLang/julia/issues/24614)) should be covariant, but for now they are intentionally invariant. The main motivation was of course missing data, where allowing `Union{T,Missing}` as the field type of a concrete type is potentially useful.
