[ANN] TypeCompletion.jl: exploit redundancy to complete UnionAll types

Repo: Neven Sajko / TypeCompletion.jl · GitLab

General registry PR: New package: TypeCompletion v1.0.0 by JuliaRegistrator · Pull Request #106387 · JuliaRegistries/General · GitHub

As documented (in the doc strings), overload complete_overload and then call complete(your_type).

Just gonna copy the README.md below. NB: the JuliaHub links below will only be able to work after registration.

TypeCompletion.jl

A Julia package providing an interface for completing types. Useful for a type with
redundancy in its definition.

When would I want to implement the TypeCompletion.jl interface for my type?

The TypeCompletion.jl interface is useful for a type T such that every valid instance
v of T must also be an instance of S and S <: T. In such a case it makes sense to
define:

TypeCompletion.complete_overload(::Type{T}) = S

Example 1: redundancy introduced to constrain the values of some parameters

Suppose you have a type E1 and E1 has a type parameter N. Further suppose that N
should always be a nonnegative integer (perhaps it encodes a length). In such a case it
might make sense to introduce an additional redundant type parameter for extra type
safety: R<:NTuple{N,Nothing} (the Nothing is arbitrary). For example:

struct E1{Length,R<:NTuple{Length,Nothing}} end

E1{L} could ideally be completed to E1{L,NTuple{L,Nothing}}, likewise with
E1{<:Any,NTuple{L,Nothing}}. To enable these completions, define:

const nonredundant_alias = E1{L,NTuple{L,Nothing}} where {L}
TypeCompletion.complete_overload(::Type{E1{L}}) where {L} = nonredundant_alias{L}
TypeCompletion.complete_overload(::Type{E1{<:Any,NTuple{L,Nothing}}}) where {L} = nonredundant_alias{L}

Implementing TypeCompletion.complete_overload helps minimize the inconvenience to
users caused by the existence of the redundant type parameter.

Example 2: redundancy introduced to define subtyping relative to an abstract type

Suppose you have a type E2 such that E2{A} should subtype AbstractVector{A}. This
necessitates having A as one of the type parameters. Further suppose that E2 wraps
some other AbstractVector{A} value, so we also want another type parameter,
B<:AbstractVector{A}. Thus there is redundancy in the type parameters of E2, so
TypeCompletion.jl might be useful. Suppose, then, this is the definition of E2:

struct E2{A, B<:AbstractVector{A}} <: AbstractVector{A} end

E2{<:Any,Vector{Int}} could ideally be completed to E2{Int,Vector{Int}}. To enable
this, define:

function TypeCompletion.complete_overload(::Type{E2{<:Any,B}}) where {A,B<:AbstractVector{A}}
  E2{A,B}
end
1 Like

This is used in the StaticViews.jl package (which will be submitted for registration after this one is registered). So look here for more example usage: Neven Sajko / StaticViews.jl · GitLab