Edit: it was just a syntax error, that is being reported a bit misleadingly and led me astray
I was playing with defining convoluted types and stumbled upon this behavior:
julia> struct S{T} <: AbstractVector{T} where {T<:Integer} end
ERROR: invalid subtyping in definition of S: can only subtype data types.
I think it is happening because typeof(AbstractVector) == UnionAll
instead of DataType
. Could someone hand-hold me through an explanation of why this is forbidden? Not just the dry rule “can not subtype UnionAll”, but focusing more on the “why”, what becomes unwieldy and unpleasant for the dispatcher and compiler?
Edit: Another way to ask the question is what is the difference between the following two attempts that I initially thought are the same, but it seems only one of them works:
julia> struct S1{T <: Integer} <: AbstractVector{T} end
# works fine
julia> struct S2{T} <: AbstractVector{T} where {T <: Integer} end
ERROR: invalid subtyping in definition of S2: can only subtype data types.
As to why I was trying to do this, I describe it in the block below, but I suspect it is not important - I will figure out some other way to do it. It had to do with defining new Symbolic operators with Symbolics.jl. I am describing it here, because maybe the creators of Symbolics have faced similar issues.
Click to expand the initial reason I stumbled upon this
I wanted to define a bunch of symbolic objects that have mostly the same behaviors and interfaces and internal structure, but which print slightly differently. For example
struct SymbolicTensorProductOfKets <: Symbolic{Ket} terms end
and
struct SymbolicTensorProductOfOperators <: Symbolic{Operator} terms end
So I thought it would make sense to define
struct SymbolicTensorProduct{T} <: Symbolic{T} where {T <: Union{Ket,Operator}} terms end
but that does not work.