We've been experimenting with synthesizing conformances to AdditiveArithmetic (and other protocols) as part of differentiable programming in Swift, and we'd like to start pitching these through Swift Evolution.
AdditiveArithmetic generalizes types that define addition, subtraction, and a zero. Conforming types include both numeric scalar types, like Int and Float, as well as vector types like SIMD4<Double> (this is not implemented yet because of ABI concerns).
Similar to Equatable and Hashable synthesis, AdditiveArithmetic conformance synthesis for structs works when all stored properties conform to AdditiveArithmetic.
struct Point<T: AdditiveArithmetic>: @memberwise AdditiveArithmetic {
var x, y: T
// Compiler synthesizes:
static var zero: Point {
return Point(x: T.zero, y: T.zero)
}
static func + (lhs: Point, rhs: Point) -> Point {
return Point(x: lhs.x + rhs.x, y: rhs.y + rhs.y)
}
static func - (lhs: Point, rhs: Point) -> Point {
return Point(x: lhs.x - rhs.x, y: rhs.y - rhs.y)
}
static func += (lhs: inout Point, rhs: Point) {
lhs.x += rhs.x
lhs.y += rhs.y
}
static func -= (lhs: inout Point, rhs: Point) {
lhs.x -= rhs.x
lhs.y -= rhs.y
}
}
var point = Point<Float>(x: 2, y: 3)
print(point + point) // Point<Float>(x: 4.0, y: 6.0)
print(Point<Float>.zero) // Point<Float>(x: 0.0, y: 0.0)
We believe AdditiveArithmetic conformance synthesis is important for numerical computing: it makes aggregates of numeric scalars or vectors just work with addition. Currently, it’s an important usability feature for differentiable programming in Swift.
Edit: As some have pointed out, memberwise derivation of AdditiveArithmetic doesn't make sense as a default implementation in all cases, unlike Equatable and Hashable synthesis. Thus, derivation is gated by the @memberwise attribute.
Feedback is welcome!