I probably won’t have a complete answer, but here are a few responses:
- Your syntax looks weird because you’re actually mixing two entirely different ways of specifying parametric methods: the pre-v0.6 version with
f{T}
and the post-v0.6where T
syntax. The former is being removed, since it’s confusing: PSA: Parametric method syntax deprecation about to drop
So instead, an equivalent definition in the modern syntax is:
function unpack(v::Array{T, N}) where {M, U, T <: NTuple{M, U}, N}
...
which hopefully makes it more clear what all the type variables are doing.
-
Your definition actually creates infinitely many methods, since there are infinitely many values of
M
,U
, etc. So it wouldn’t make sense formethods
to list all of them. Instead it’s showing you that you’ve defined one method, but with free variablesN, M, U
which will be filled in from whatever arguments you specify (and thus new native code will be generated for each differentN
,M
, andU
) -
They’re only necessary if you actually need to refer to the type variables inside the function (which your current implementation does). But I think there’s a cleaner implementation that doesn’t need any of this:
function myunpack(v::Array{<:NTuple{N}}) where {N}
ntuple(i -> getindex.(v, i), Val{N})
end
this does two levels of broadcasting: for each i in 1:N
it calls getindex.(v, i)
, which itself broadcasts the getindex
call across each element of v
.
Does this perform well enough for your use case?
Also, please use BenchmarkTools.jl to time your code, to avoid accidentally including compile time.