Type system limitations

Conceptually I want to do something like

function f(x::V{T}, y::W{U}) where V where T where W where U
    yy = convert(V{U}, y)
   ...
end

which is not possible, and seems to be a common problem (https://discourse.julialang.org/t/how-to-get-the-container-type-of-a-container, https://discourse.julialang.org/t/stripping-parameter-from-parametric-types/, https://discourse.julialang.org/t/extract-type-name-only-from-parametric-type/)

Maybe someone who knows the internals of the type system can explain if this is something that could be implemented in the future (and if there are plans to do so) or if this is something that is not possible due to general limitations of how the type system in Julia works.

I think it’s probably super hacky so you most likely shouldn’t rely on it, but basetype(V){U} would work where you could steal the definition of basetype from https://github.com/marius311/CMBLensing.jl/blob/1bfec09447b5ead5a77f404006af97a1d462729e/src/util.jl#L120

The order of type parameters can be somewhat arbitrary and affected by other considerations (eg the most frequently used ones usually come first since that is a bit more convenient for parametric dispatch), so they should not be something to rely on.

In fact, they may not even exist:

struct HyperSpecializedVector <: AbstractVector{Float64} end
Base.size(::HyperSpecializedVector) = (7, )
Base.getindex(::HyperSpecializedVector, ::Int) = 0.444

is a subtype of AbstractArray that implements the interface, but has no type parameters.

So, in a nutshell, this kind of method dispatch is not very generic or useful as a design pattern.

You may want to give more context about your problem, so that an idiomatic solution can be suggested. I frequently find that generic APIs, possibly combined with traits, can provide an effective, convenient, and extensible solution.

1 Like

This was basically my first intuition to solve the issue here without having to add an extra dependency on StaticArrays.jl. I have solved it in a quite non-idiomatic way by checking the element type here. The solution works fine but doesn’t feel very elegant.

Without building your own type, BitArray{N} <: AbstractArray{Bool, N}

1 Like

Somewhat related: https://docs.julialang.org/en/v1/manual/methods/#Design-Patterns-with-Parametric-Methods-1, in particular eltype.

1 Like