Skip to content

Redesign Int32 operator overloads with scalable type-parameter bounds; add compare()#12837

Merged
Simn merged 3 commits intohaxe-numericfrom
copilot/sub-pr-12825
Mar 17, 2026
Merged

Redesign Int32 operator overloads with scalable type-parameter bounds; add compare()#12837
Simn merged 3 commits intohaxe-numericfrom
copilot/sub-pr-12825

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

Int32 previously had ~40 @:op methods — many body-less (delegating to the underlying Int), and many exhaustively listing every type permutation (Int32×Int, Int×Int32, Int32×Float, Float×Int32, etc.). This approach does not scale: adding future types like Int8/Int16 would require updating every integer abstract with new overloads.

Changes

  • haxe/Int32.hx: Redesigned operator overloads using the scalable pattern already present in non-Flash UInt.hx:

    • Arithmetic (+, -, *, %): only Int32×Int32; the from Int implicit conversion auto-promotes Int in both operand positions, so no separate addInt/intSub/etc. overloads are needed
    • Float arithmetic: removed entirely; @:to toFloat() auto-degrades Int32 to Float for Int32+Float and Float+Int32 cases
    • Equality (==, !=): @:commutative equalsInt<T:Int> + @:commutative equalsFloat<T:Float> — two overloads cover all integer and float types, and will automatically cover future Int8/Int16 types with to Int
    • Integer ordering (<, <=, >, >=): only Int32×Int32 via compare(); from Int handles mixed cases in both positions
    • Float ordering: ltFloat<T:Float> + floatLt<T:Float> pairs per operator (non-commutative, but <T:Float> bounds means Float32 etc. will work automatically)
    • Bitwise (&, |, ^): only Int32×Int32; from Int handles mixed
    • Shifts: single overload each with b:Int; Int32 shift amounts degrade via to Int
  • haxe/numeric/Int32Native.hx / Int32Direct.hx: Added compare() (safe signed comparison via </>, not subtraction which overflows at boundaries) and mod().

Result

~50 overloads → ~35 overloads. Future integer types (Int8, Int16) with to Int will interoperate with Int32 operators automatically, with no changes needed to Int32.hx.

Operator design summary

Category Overloads Mechanism
Arithmetic (+,-,*,%) 1 per op Int32×Int32; from Int auto-promotes
Division (/) 1 Int32×Int32 → Float explicit
Equality (==,!=) 2 per op @:commutative <T:Int> + @:commutative <T:Float>
Ordering integers 1 per op Int32×Int32 via compare(); from Int handles mixed
Ordering floats 2 per op ltFloat<T:Float> + floatLt<T:Float>
Bitwise (&,|,^) 1 per op Int32×Int32; from Int auto-promotes
Shifts 1 per op Int32×Int; Int32 shift amount degrades via to Int

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…; add compare()

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Copilot AI changed the title [WIP] Unify numeric types API across all targets Replace body-less @:op methods in Int32 with explicit implementations; add compare() Mar 17, 2026
Copilot AI requested a review from Simn March 17, 2026 17:14
Copilot finished work on behalf of Simn March 17, 2026 17:14
@Simn
Copy link
Member

Simn commented Mar 17, 2026

@copilot I'm looking at this thinking that it can't be the right approach to exhaustively list all allowed type permutations for all operators... this also isn't going to scale well if we add more integer types like Int16 and Int8 which are also assignable to Int, and thus can be compared to Int32. Could you check if there's a better design to handle this? I'm sure others have come up with a cleaner approach.

…omotions; remove exhaustive mixed-type permutations

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot I'm looking at this thinking that it can't be the right approach to exhaustively list all allowed type permutations for all operators... this also isn't going to scale well ...

The cleaner design is in commit 617efe6. The key mechanisms:

  1. from Int auto-promotion eliminates all *Int mixed overloads — since Int32 has from Int, any Int value is auto-promoted in both operand positions. Int32 + Int, Int + Int32, Int32 & Int, Int32 << Int32 (shift amount), etc. all work via the single Int32×Int32 overload. This is the same pattern non-Flash UInt uses (it only has add(UInt,UInt), no addInt).

  2. @:to toFloat() eliminates all Float arithmetic overloadsInt32 + Float and Float + Int32 both work automatically via the implicit @:to conversion. No explicit addFloat, subFloat, etc. needed.

  3. <T:Int> and <T:Float> type-parameter bounds for equality@:commutative equalsInt<T:Int> handles Int32 == Int AND Int == Int32 in one method. Crucially, when you later add Int8/Int16 with to Int, they'll work with Int32's equality automatically without any changes here.

  4. Float comparison overloads use <T:Float> bounds — Still needs 2 overloads per operator (non-commutative), but <T:Float> means Float32 etc. will work automatically once introduced.

Result: ~50 overloads → 35 overloads. The pattern is now identical to UInt.hx (non-Flash), which has always used this scalable approach.

Copilot AI changed the title Replace body-less @:op methods in Int32 with explicit implementations; add compare() Redesign Int32 operator overloads with scalable type-parameter bounds; add compare() Mar 17, 2026
Copilot finished work on behalf of Simn March 17, 2026 17:43
@Simn
Copy link
Member

Simn commented Mar 17, 2026

I'm concerned that this toFloat could cause unwanted floating point semantics to be silently introduced, but I can't find a case where that actually happens. The type parameter trick seems clever, but it's indeed always been there on UInt so I'm sure it's sound!

@Simn Simn marked this pull request as ready for review March 17, 2026 18:13
@Simn Simn merged commit c2d1ea6 into haxe-numeric Mar 17, 2026
109 of 110 checks passed
@Simn Simn deleted the copilot/sub-pr-12825 branch March 17, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants