# Null and Array of T question

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
``````
1 Like

Ok, I got it. So this works too:

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

The first is false because types in Julia are invariant (except Tuples), i.e. `eltype([1, null, 2])<:Union{Nulls.Null,T} where T <: Number` does not imply `typeof([1, null, 2]) <: Array{Union{Nulls.Null,T} where T <: Number}`. See https://docs.julialang.org/en/stable/manual/types/#Parametric-Composite-Types-1

1 Like