Hey all,
I've been working on several small prototypes of this ever since SE-0452 originally introduced integer generic parameters and mentioned arithmetic generics in the "Future directions" section. Since SE-0531 (literal expressions in integer generic argument positions) got accepted recently too, I decided to make another prototype and got far enough this time that I wanted to pitch it for real.
Basically, Swift still cannot use arithmetic with integer generic parameters in generic argument positions to do things like this:
struct Vector<let count: Int, Element> {}
func concatenated<let lhsCount: Int, let rhsCount: Int, Element>(
_ lhs: Vector<lhsCount, Element>,
_ rhs: Vector<rhsCount, Element>
) -> Vector<(lhsCount + rhsCount), Element>
The pitch keeps SE-0531's required parentheses, but extends the expressions inside them to include integer generic parameters and a bounded set of Int operations. In my prototype, the signature above is accepted, allowing the result type to retain the relationship between its input sizes.
Literal subexpressions continue to use SE-0531's existing folding rules. For example, Vector<(count + (2 + 3)), Element> still becomes Vector<(count + 5), Element>. The dependent generic part of an expression retains its ordered tree though: Vector<(n + m), Element> and Vector<(m + n), Element> are distinct. I initially tried to add a more general algebraic-equivalence system, but obviously the complexity of that really ballooned, even when my prototype was just working with + and * operators. I think keeping the whole expression tree structure ended up making the most sense for many reasons.
I've currently got support for all of the Int arithmetic, bitwise, shift, and unary operators supported by the literal expressions from SE-0531. For now, division and remainder require a divisor that SE-0531 can fold to a nonzero integer. Supporting a dependent divisor would require a way to state a divisor != 0 constraint in a generic signature, which this pitch deliberately leaves out of scope.
This is my first pitch (and first post!) even though I've followed the Swift Evolution forums for several years now. I'm really looking forward to hearing your feedback and thoughts!
The current proposal draft is here:
The compiler prototype and tests are here:
https://github.com/Brennanium/swift/tree/dependent-integer-generic-expressions