Difference between `Union{Missing, Float64}` and `Float64?`

Good question.
I had some time today to investigate and came up with the following conclusion: it’s just a matter of display real estate.
If the column name is short, then there would not be enough space to fit the Union{...} header

julia> DataFrame(a = [1,2,3,missing])
4×1 DataFrame
│ Row │ a       │
│     │ Int64?  │
├─────┼─────────┤
│ 1   │ 1       │
│ 2   │ 2       │
│ 3   │ 3       │
│ 4   │ missing │

However, if the column name is long enough, then the Union{...} type name representation would fit and so would be used:

julia> DataFrame(a12345678912345678901 = [1,2,3,missing])
4×1 DataFrame
│ Row │ a12345678912345678901 │
│     │ Union{Missing, Int64} │
├─────┼───────────────────────┤
│ 1   │ 1                     │
│ 2   │ 2                     │
│ 3   │ 3                     │
│ 4   │ missing               │
5 Likes