I am trying to understanding how array operations work and how types work inside arrays. The system is Julia Pro 0.6.0.1 on 64bit Windows 7

The motivating example was

using Nulls
x = [1, null, 2]
typeof(x) # gives Vector{Union{Int64, Nulls.Null}}
y = x + 2
typeof(y) # gives Vector{Any}

So the type of vector changed which isn’t the behaviour I expected. I expected it to have remained at Vector{Union{Int64, Nulls.Null}}

The below is also puzzling. I thought all 3 definitions of the function ok should work. But it appears only the last one works. It seems that there is something going on with the interaction of arrays and types that I don’t fully understand. Please help to explain the behavior and if there are “rules” to let me work out how it works. Thanks

using Nulls
function ok(A::Array{Union{T,Nulls.Null} where T <: Number}, B::Number)
return 1
end
@which ok([1, null, 2],2)
function ok(A::Array{Union{Integer,Nulls.Null}}, B::Number)
return 1
end
@which ok([1, null, 2],2)
function ok(A::Array{Union{Int64,Nulls.Null}}, B::Number)
return 1
end
@which ok([1, null, 2],2)

I suspect your y = x + 2 example is a bug. The machinery to deal efficiently with Union{T,Null} types is very recent and still a bit of a work in progress. Maybe @quinnj can confirm.

The method definition should read:

function ok(A::Array{Union{T,Nulls.Null}}, B::Number) where T <: Number
return 1
end

This is fairly subtle and I don’t think I can explain it. But essentially the reason it was not dispatched to your method is:

julia> [1, null, 2] isa Array{Union{T,Nulls.Null} where T <: Number}
false

julia> function okkk(A::Array{Union{T,Nulls.Null}} where T<:Number, B::Number)
return 1
end
okkk (generic function with 1 method)
julia> okkk([1,null],1)
1

the reason is:

julia> [1, null, 2] isa Array{Union{Nulls.Null,T} where T <: Number}
false
julia> [1, null, 2] isa Array{Union{Nulls.Null,T}} where T <: Number
true