Why is type promotion asymmetric in `append!`? `append!([1.1],[1])` vs `append!([1],[1.1])`

Why is this is fine:

julia> append!([1.1],[1])
2-element Vector{Float64}:
 1.1
 1.0

but this not?

julia> append!([1],[1.1])
ERROR: InexactError: Int64(1.1)

I find this strange when this is fine:

julia> vcat([1], 1.1)
2-element Vector{Float64}:
 1.0
 1.1

And when arrays can have mixed type:

julia> [1, "a"]
2-element Vector{Any}:
 1
  "a"

In the first two examples. Append means taking an element and putting it into an existing array. Arrays cannot change type. Therefore Julia tries to convert the element to the type of the array. In the first case (int to float), this is possible:

julia> append!([1.1],[1])
2-element Vector{Float64}:
 1.1
 1.0

But in the other case (float to int) it is not. Note that even in the first case, the type of the array did not change. It is still a Vector{Float64} after you added a new element.

julia> append!([1],[1.1])
ERROR: InexactError: Int64(1.1)

The following example uses vcat: “Take these two things and create an array with them.” As you are already creating a new array, it is possible to look for the largest type that can hold all the values and use that one.

julia> vcat([1], 1.1)
2-element Vector{Float64}:
 1.0
 1.1

And when arrays can have mixed type:

They do, but once they are created, you cannot change the type; that is why your first example fails.

5 Likes

This makes sense. Your answers helped reinforce a few things. append! is not a “symmetric” or “commutative” function. You don’t append one thing and another, you append something to something. So I should be careful about what I am appending and what I am appending to. And vcat creates a new array altogether.

1 Like