# Julia typesystem

**URL:** <https://discourse.julialang.org/t/julia-typesystem/121860>\
**Category:** New to Julia\
**Created:** [October 28, 2024, 9:46am UTC](https://discourse.julialang.org/t/julia-typesystem/121860 "2024-10-28T09:46:42Z")\
**Posts on this page:** 3\
**Page:** 2

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [October 28, 2024, 12:02pm UTC](https://discourse.julialang.org/t/julia-typesystem/121860/21 "2024-10-28T12:02:06Z")

</div>

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
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"]`.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [October 28, 2024, 2:27pm UTC](https://discourse.julialang.org/t/julia-typesystem/121860/22 "2024-10-28T14:27:42Z")

</div>

> [@world-peace](#):
>
> btw… how did you obtain this information? This is from my REPL:

You can also see what happens at various stages with:

```julia
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"]

```

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [October 29, 2024, 12:12pm UTC](https://discourse.julialang.org/t/julia-typesystem/121860/23 "2024-10-29T12:12:06Z")

</div>

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

Here’s some (hopefully?) interesting findings.

```julia
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.

[Previous page](https://discourse.julialang.org/t/julia-typesystem/121860.md?page=1)
