Shouldn't HasShape trait subtype HasLength?

The HasLength and HasShape generator traits are defined as follows

  • HasLength() if there is a fixed, finite length.
  • HasShape() if there is a known length plus a notion of multidimensional shape (as for an array).

This suggests that any method that can accept a HasLength generator should be able to deal with a HasShape one as well. However since these traits make a flat hierarchy, a method defined as

f(::HasLength, iter) = ..

would not accept e.g. an array.

The way things are currently set up, with the convention that methods should be written

f(::HasLength, iter) = ..

and not

f(::Type{HasLength}, iter) = ..

(as you had it before your edit), both HasLength and HasShape need to be instantiable, and hence need to be concrete types. Julia doesn’t allow inheritance from concrete types, so HasShape can’t subtype HasLength.

I do think that this would be possible if the convention were to use methods of the latter form above, and to have HasLength, HasShape etc. all be abstract types. I’m not sure why the former form was chosen.

Do note that you can currently always do

f(::Union{HasLength, HasShape}, iter) = ..

(as is often done in practice), which I suppose isn’t that much worse than

f(::Type{<:HasLength}, iter) = ..

with a hypothetical abstract HasShape and HasShape <: HasLength.