Operator Overloading
Operators in Kestrel are dispatched through protocols. To make + work on your type, conform to the protocol that defines +.
Conforming to an arithmetic protocol
struct Vec2 {
let x: Float64
let y: Float64
}
extend Vec2: Addable {
type Output = Vec2
public static var zero: Vec2 { Vec2(x: 0.0, y: 0.0) }
public consuming func add(consuming other: Vec2) -> Vec2 {
Vec2(x: self.x + other.x, y: self.y + other.y)
}
}
let v = Vec2(x: 1.0, y: 2.0) + Vec2(x: 3.0, y: 4.0); // Vec2(4, 6)
Addable requires three members: an Output associated type (the result type of + — usually Self), a static zero (the additive identity, which gives APIs like sum() a starting point), and a consuming func add. The compiler rewrites a + b into a.add(b) for any conforming type.
The same pattern applies to - (Subtractable), * (Multipliable, which also asks for a static one), / (Divisible), and % (Modulo). Equality and ordering are shaped differently — see below.
Equality
Equality (==) goes through Equatable:
extend Vec2: Equatable {
public func isEqual(to other: Vec2) -> Bool {
self.x == other.x and self.y == other.y
}
}
let v1 = Vec2(x: 1.0, y: 2.0);
let v2 = Vec2(x: 1.0, y: 2.0);
v1 == v2; // true — calls v1.isEqual(to: v2)
Conforming to Equatable is also a prerequisite for using a type as a dictionary key (which additionally requires Hashable) or in a Set.
Comparable
Ordering (<, >, <=, >=) goes through Comparable:
struct Length {
let meters: Float64
}
extend Length: Comparable {
public func isEqual(to other: Length) -> Bool {
self.meters == other.meters
}
public func compare(other: Length) -> Ordering {
self.meters.compare(other.meters)
}
}
let short = Length(meters: 1.0);
let long = Length(meters: 100.0);
short < long; // true
compare returns an Ordering — .Less, .Equal, or .Greater. The compiler derives all four ordering operators from this single method. Comparable refines Equatable, so you must also provide isEqual.
When to overload
Overload operators when the type really is numeric or orderable in a way readers will recognize at a glance — vectors, money, durations, points. Don't overload to be cute; an unfamiliar type with overloaded + makes call sites read worse, not better. If the operation needs a name to be understood, give it one.
For the canonical operator-to-protocol mapping, see Reference → Operators.