Type Stability: Collections of Abstract Types

You can inform the return type of getproperty, and that improves a little bit things:

function getFirstColor2(A::Vector{<:Home{String}})
    return A[1].color::String
end

julia> @code_warntype getFirstColor2(myHomes)
Variables
  #self#::Core.Const(getFirstColor2)
  A::Vector{Home{String}}

Body::String
1 ─ %1 = Base.getindex(A, 1)::Home{String}
│   %2 = Base.getproperty(%1, :color)::Any
│   %3 = Core.typeassert(%2, Main.String)::String
└──      return %3

At least the return type is correct and possible instabilities won’t scape this function.

It gets a little bit better if the list is defined with a union of a small number of types, such as:

myHomes2 = Union{Condo{String},Apartment{String}}[Condo("Red"), Apartment("Blue")]

You get a better output even with your original function:

julia> @code_warntype getFirstColor(myHomes2)
Variables
  #self#::Core.Const(getFirstColor)
  A::Vector{Union{Apartment{String}, Condo{String}}}

Body::String
1 ─ %1 = Base.getindex(A, 1)::Union{Apartment{String}, Condo{String}}
│   %2 = Base.getproperty(%1, :color)::String
└──      return %2

But arrays of mixed types result to never be ideal, at some point the compiler will quit trying to infer the return types.

Note that nothing prevents you from defining

struct House{T} <: Home{T}
   color::Int
end

thus, there in an intrinsic indefinition of the type of color, even with the parameter T.

1 Like