Questiosn about `where` for function definitions (while unpacking arrays of tuples)

I probably won’t have a complete answer, but here are a few responses:

  1. 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.6 where 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.

  1. Your definition actually creates infinitely many methods, since there are infinitely many values of M, U, etc. So it wouldn’t make sense for methods to list all of them. Instead it’s showing you that you’ve defined one method, but with free variables N, M, U which will be filled in from whatever arguments you specify (and thus new native code will be generated for each different N, M, and U)

  2. 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.

1 Like