Skip to content

✨ towards a broadcasting-aware rank-typing framwork #538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2025

Conversation

jorenham
Copy link
Member

@jorenham jorenham commented May 4, 2025

This adds several new type-check-only types to _numtype, which can be divided into two categories: Rank-types, and broadcast type-aliases.

The rank-types subclass and wrap the integer tuples that are currently used as shape-types. This makes them backwards-compatible (after modifying ndarray.shape), while making it possible to embed static-typing information, such as the broadcasting rules, into these types, as type-check-only methods or attributes.

  • Rank0 <: ()
  • Rank1 <: (int,)
  • Rank2 <: (int, int)
  • Rank3 <: (int, int, int)
  • Rank4 <: (int, int, int, int)
  • Rank0ToN <: (int, ...)
  • Rank1ToN <: (int, *(int, ...))
  • Rank2ToN <: (int, int, *(int, ...))
  • Rank3ToN <: (int, int, int, *(int, ...))
  • Rank4ToN <: (int, int, int, int, *(int, ...))

Another advantage (usually), is that these types don't have a mutual subtyping relation, unlike their tuple base types. So e.g. Rank0 is not assignable to Rank0ToN. This makes a lot easier, since there's no need to worry about overlapping overloads, complex constraint-set solvers.

The most important usecases is broadcasting. For rank-typing purposes, broadcasting two ranks is equivalent to taking the maximum of the two. Most of the this static-typing machinery is basically an implementation such a maximum (and a minimum) function, disguised as a type-alias called Broadcastable (and Broadcaster for the minimum). For example, r: Broadcastable[tuple[int]] accepts Rank0, Rank1, Rank0ToN, and Rank1ToN, but rejects all other rank types. It does not accept bare integer tuples, and instead has to be used "the other way around", i.e. by passing the bare integer tuples to the Broadcastable type, or its mirror image, the Broadcaster type.

The plan is to gradually start integrating these types, and iterate on them whenever it turns out to be necessary. I also plan to embedding the shaped array-like types in the rank-types, so that it's statically known that arrays of Rank2 accept Sequence[Sequence[T]], which could help make things more readable, maintainable, DRY, and pretty.

I may also add some more rank-types later on, as I expect that e.g. Rank1To2 is going to be useful to have (unions are smelly after all).

towards #539

@jorenham jorenham mentioned this pull request May 4, 2025
@jorenham jorenham merged commit 00a20dd into main May 4, 2025
19 checks passed
@jorenham jorenham deleted the rank-typing-prologue branch May 4, 2025 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant