Thanks for the attention! I’ll probably close these PRs as I’m working on a new design, but probably it’ll be a package for some time before I try to upstream it.
The idea with the open PRs was to keep, together with a tuple, a singleton type representing the length of a view into the tuple.
The idea that I’m currently experimenting with is to create a new recursive data structure for a constant-size heterogeneous collection. The first thing I tried was simply something like this:
struct HeterogeneousList{ElementType,Rest}
first_element::ElementType
# When `rest` isn't a `HeterogeneousList`, the object represents an empty collection
rest::Rest
end
A problem with the above design was that there’s no way to describe, e.g., a list of indeterminate length, all of whose elements are Int (Tuple{Vararg{Int}} in tuple parlance), or a list whose first element is Bool while any others are Int (Tuple{Bool,Vararg{Int}} in tuple parlance).
The current design looks like this:
- There’s a homogeneous list type (representing a constant-length homogeneous collection, so all elements are of the same type)
- Then the heterogeneous list type is implemented as a list of “homogeneous extents”, each of which is a homogeneous list. The idea is for each homogeneous extent to be maximal
This design is actually supposed to allow more descriptive power than the combination of Tuple and Vararg, as it should allow describing types such as “an indeterminate number of Ints, terminated by a Bool”. This is something that’s not possible to describe as a tuple type in Julia’s type system. In the end this should allow for improved inference, especially with abstract argument types. For example, currently an operation such as reverse loses information when given a tuple type with Vararg:
julia> f(t) = reverse(reverse(t))
f (generic function with 1 method)
julia> Core.Compiler.return_type(f, Tuple{Tuple{Int,Vararg{Bool}}})
Tuple
Ideally, the inferred type would be Tuple{Int,Vararg{Bool}} instead of just Tuple, and my design above should allow for that.
In practice my package would probably be used like so:
- convert a tuple to a heterogeneous list
- apply the required operations on the heterogeneous list instead of on the tuple
- convert the result back to
Tuple