Using `end` when `size` is not definable

This is an odd question so let me motivate it by an example. Say we have a Vector of Vectors: a = [[3];[2;3];[3;1]]. These types may be easier to handle if one could directly index them, so we define a wrapper type VecVec with the indexing scheme a[i,j] = a[i][j]. Using dispatches we can define :, so a[:,1] creates a vector which is the first component of each. This all makes sense. This has a natural length to it, which is not the number of elements, but the length of the actual higher level vector.

However, there is no definable size because that would guarantee that its a vector of vectors, where each internal vector has the same size. This means that end doesn’t work: a[2:end,1] doesn’t work. However, there is a proper invariant that end can mean for the first dimension, and that is a[2:length(a),1].

Is there a way to be able to specify that exact relationship? Or does one have to resort to size, which isn’t always definable in this case? Note that having all of the vectors the same size is a common property, so maybe if there was a way to conditionally have a size for a VecVec I would be fine, but is there a way to do that without duplicating the type? The way I can think of doing it is:

  1. Duplicate the type
  2. Make an abstract type which covers them
  3. Make all of the previous dispatches to the abstract type
  4. Add a specific dispatch for size to one of them

But the problem here is that, for my actual use case this will lead to non-inferability of the type.

So is there a good way to do this? Or should I just give up and say “use length in the first dimension”?

[For reference this is related to an open issue: https://github.com/JuliaDiffEq/DifferentialEquations.jl/issues/123]

1 Like

Why not define size(x, dim) and have it fail when n != 1?

That totally escaped me. Thanks, works great.