Dear fellow Julians,
I’m currently trying to design a package for computational differential geometry, and I’ve encountered a few places in my design where a certain enhancement of the dispatch semantics would be of great help for simplification and improving robustness.
Consider a parametric abstract base type like follows
abstract type AbstractLinearVector{N,T,S} <: FieldVector{N,T} end
where N is the size of the vector, T the element type and S an abstract type that indicates the space the vector lives in. The latter is only there for using it as a dispatch parameter. StaticArrays provides the FieldVector supertype.
A concrete vector type would be created from a parametric type that could for example be
struct TangentVector3{T} <: AbstractLinearVector{3,T,AbstractTangentSpace}
x::T; y::T; z::T
end
The user of the package is supposed to define custom vectors like this for whatever space is introduced. However, there should be some common behaviour for all subtypes of AbstractLinearVector. For example, I wish to have a common set of promotion rules. The only way Julia offers this right now would be to manually define a promotion rule for each newly introduced vector. Clearly, this could be simplified using macros, but it would complicate the design and the usage of the package.
If one could however simply write something like
promote_rule( ::Type{U{T1}<:AbstractLinearVector{N,T1,S}}, ::Type{U(T2)<:AbstractLinearVector{N,T2,S}} ) where {U,N,T1,T2,S} = U(promote_type(T1,T2))
with the intuitive meaning of dispatching on only subtypes of AbstractLinearVector if both arguments have the same subtype, but with a different single parameter and share common supertype parameters N and S. It would also allow the use of the subtype in the function definition and be compatible with @generated
. Unlike constructs like U::Type{<:AbstractLinearVector{N,T1,S}, which would not reveal the parameter or the stripped type and be incompatible with @generated
.
The idea could be extended to cover arbitrary subtype-chains and to work for non-type arguments. This can be useful for defining type-stable operators, for example.
I’m not familiar enough with the internals of multiple dispatch to be able to judge if something like this is feasible at all. In case I’m missing a powerful feature that makes this superfluous, I would love to learn about it.
Thanks,
Andreas