Suggestion: introduce something like a @inferable or @typestable macro to the language

A better description (hopefully): each element of an Array (or other container) has it’s own concrete type, but the type of the container value doesn’t necessarily encode fully the types of the elements. For example:

julia> [nothing, missing]
2-element Vector{Union{Missing, Nothing}}:
 nothing
 missing

julia> [Val{1}(), Val{2}()]
2-element Vector{Val}:
 Val{1}()
 Val{2}()

julia> struct A end

julia> struct B end

julia> [A(), B()]
2-element Vector{Any}:
 A()
 B()

julia> Union{A, B}[A(), B()]
2-element Vector{Union{A, B}}:
 A()
 B()

In each of these examples the vector elements have a certain concrete type: abstract types can’t have instances. But abstract types can be type parameters to other types, such as container types, like Array.

Quoting Types · The Julia Language

There is no meaningful concept of a “compile-time type”: the only type a value has is its actual type when the program is running. This is called a “run-time type” in object-oriented languages where the combination of static compilation with polymorphism makes this distinction significant.

Only values, not variables, have types – variables are simply names bound to values, although for simplicity we may say “type of a variable” as shorthand for “type of the value to which a variable refers”.

2 Likes