Julia typesystem

So, when [1,2,3,"hello"] is encountered, it’s (more or less) lowered to Base.vect(1,2,3,"hello"). Base.vect will construct a vector, it needs an element type. The element type is found with Base.promote_typeof(1,2,3,"hello"), which returns “Any” (essentially, promote_type(Int,Int,Int,String)).

It can be changed, but that’s type piracy if none of the types are your own.

julia> Base.promote_rule(::Type{Int}, ::Type{String}) = Union{Int,String}
julia> [1,2,"foo"]
3-element Vector{Union{Int64, String}}:
 1
 2
  "foo"

julia> Base.promote_rule(::Type{Int}, ::Type{String}) = Union{Integer,String}
julia> [1,2,"foo"]
3-element Vector{Union{Integer, String}}:
 1
 2
  "foo"

julia> [1,2.0,"foo"]
3-element Vector{Any}:
 1
 2.0
  "foo"

It’s of course much safer to create your vector as Union{Int,String}[1,2,3,"hello"].

2 Likes

You can also see what happens at various stages with:

julia> dump(:([1,2,3,"hello"]))
Expr
  head: Symbol vect
  args: Array{Any}((4,))
    1: Int64 1
    2: Int64 2
    3: Int64 3
    4: String "hello"

julia> @code_lowered [1,2,3,"hello"]
julia> @code_typed [1,2,3,"hello"]

In fact, I have just been playing around with the promote_type concept.

Here’s some (hopefully?) interesting findings.

julia> promote_type(Int64, Float64)
Float64

julia> promote_type(Int64, Float64, String)
Any

julia> promote_type(Int64, Float64, Int64)
Float64

julia> promote_type(Int64, Float64, Int64, Int64)
Float64

julia> promote_type(Int64, Int8, Int64, Int64)
Int64

julia> promote_type(Int64, Int64, Int64, Int64)
Int64

julia> promote_type(Int64, Int64, Int64, Int64, Union{Int64, String})
Union{Int64, String}

# if you include an `Any` as part of a `Union` the `Union` is "optimized away"
julia> promote_type(Int64, Int64, Int64, Int64, Union{Int64, Any})
Any

julia> promote_type(Int64, Int64, Int64, Int64, Union{Int64, Float64})
Union{Float64, Int64}

# Float64 and Union{Int64, Float64} become the Union type
julia> promote_type(Int64, Int64, Int64, Int64, Union{Int64, Float64}, Float64)
Union{Float64, Int64}

Yes, I suppose it’s all quite sensible.