# Why Union{} \<: Tuple?

**URL:** <https://discourse.julialang.org/t/why-union-tuple/5946>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 18, 2017, 1:21pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946 "2017-09-18T13:21:57Z")\
**Posts on this page:** 5\
**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:** [September 18, 2017, 1:21pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946/1 "2017-09-18T13:21:57Z")

</div>

1. Why is `Union{} <: Tuple`?

2. When `Base.Broadcast._broadcast_eltype` returns `Union{}`, what does that mean? That it could not infer an eltype?

On `v"0.6.0"`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 18, 2017, 1:36pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946/2 "2017-09-18T13:36:04Z")

</div>

`Union{}` was originally `None`, renamed in Julia 0.4 ([https://github.com/JuliaLang/julia/issues/8423](https://github.com/JuliaLang/julia/issues/8423)). In Julia’s type hierarchy, this is a “bottom” type: `Union{} <: T` is `true` for _every_ type `T`, so it is at the “bottom” of the type hierarchy. (In fact, `Base.Bottom` is an alias for `Union{}`.)

My understanding is that having a bottom type made various things easier, e.g. the promotion machinery: [https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap5.tex](https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap5.tex) … it gives the type system the algebraic structure of a [lattice](https://en.wikipedia.org/wiki/Lattice_(order)), which makes it easier to reason about ([https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap3.tex](https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap3.tex)).

---

<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:** [September 18, 2017, 1:55pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946/3 "2017-09-18T13:55:06Z")

</div>

Thanks! I missed the renaming.

The issue came up when defining

```julia
"""
    fixed_tuple_fields(T)

When `T` is a `Tuple{...}` with a nonzero, fixed number of elements (ie no
`Vararg`), return those; in all other cases `()`.
"""
fixed_tuple_fields(T::Type{<:Tuple}) =
    (T.parameters[end] <: Vararg) ? () : tuple(T.parameters...)

```

How can I define this method so that it is defined for all “proper” `Tuple`s, but not `Union{}`?

---

<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:** [September 18, 2017, 2:24pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946/4 "2017-09-18T14:24:54Z")

</div>

Regarding the second question: it seems like `Union{}` is returned as an inferred type when the function does not return on any path. Eg

```julia
julia> foo(x) = error("all paths lead to an error")
foo (generic function with 1 method)

julia> Base._return_type(foo, Int)
Union{}

```

Is this correct?

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [September 18, 2017, 3:06pm UTC](https://discourse.julialang.org/t/why-union-tuple/5946/5 "2017-09-18T15:06:34Z")

</div>

> [@Tamas\_Papp](#):
>
> it seems like Union{} is returned as an inferred type when the function does not return on any path

Correct. Consider the following:

```julia
(a ? foo() : bar())

```

what’s the inferred type of that whole expression? Well it’s the union of whatever foo returns (let’s take `Union{}`) and whatever bar returns (say `Int`). I.e. it’s `Union{Union{}, Int}` and by standard type system rules:

```julia
julia> Union{Union{}, Int}
Int64

```
