Description
aka "Generalize the ANY mechanism" aka "Completely destroy Jeff's life forever"
(continuing the heresy in JuliaLang/LinearAlgebra.jl#42 in a direction that might be more profitable, but much harder)
What if we could encode an Array's size among its type parameters, but not pay the compilation price of generating specialized code for each different size?
Here's a candidate set of rules (EDITED):
- In the type declaration, you specify the default specialization behavior for the parameters:
type Bar{T,K*}
means that, by default, functions are specialized onT
but not onK
. Array might be defined astype Array{T,N,SZ*<:NTuple{N,Int}}
(in a future world of triangular dispatch). - In a function signature, if a type's parameter isn't represented as a "TypeVar", it uses the default behavior. So
foo(A::Array)
specializes the element type and the dimensionality, but not the size. - Specifying a parameter overrides the default behavior.
foo{T,K}(b::Bar{T,K})
would specialize onK
, for example. Conversely, putting * after a type parameter causes the parameter to be used in dispatch (subtying and intersection) but prevents specialization. This is much like the ANY hack now.matmul{S,T,m*,k*,n*}(A::Array{S,2,(m,k)}, B::Array{T,2,(k,n)}
would perform the size check at compile time but not specialize on those arguments.
I'm aware that this is more than a little crazy and has some serious downsides (among others, it feels like performance could get finicky). But to go even further out on a limb, one might additionally have matmul{S,T,m<=4,k<=4,n<=4}(...)
to generate specialized algorithms (note the absence of *s) for small sizes and use the unspecialized fallbacks for larger sizes. This way one wouldn't need a specialized FixedSizeArray
type, and could just implement such algorithms on Array
.
A major downside to this proposal is that calls in functions that lack complete specialization might have to be expanded like this:
if size(A,1) <= 4 && size(A,2) <= 4 && size(B,2) <= 4
C = matmul_specialized(A,B)
else
C = matmul_unspecialized(A,B)
end