Skip to content

Using Operator Overloading for Math

danieltan1517 edited this page Oct 4, 2025 · 22 revisions

When programming, there are many occasions where one wants to define addition/multiplication and different kinds of operations for a mathematical object. For example, one might define a vector or matrix and some addition/subtraction/multiplication functions to go with it.

One can define a Vec3 in the following way:

Vec3 :: struct {
    x: float;
    y: float;
    z: float;
}

Vector Addition

Given the above definition, one can overload the addition operator as follows:

operator + :: (a: Vec3, b: Vec3) -> Vec3 {
    c: Vec3;
    c.x = a.x + b.x;
    c.y = a.y + b.y;
    c.z = a.z + b.z;
    return c;
}

This is a short example demonstrating vector addition:

a := Vec3.{1, 2, 3};
b := Vec3.{3, 4, 5};
c := a + b;
print("c = %\n", c);

Vector Subtraction

Here is how one can overload the subtraction operator for Vec3.

operator - :: (a: Vec3, b: Vec3) -> Vec3 {
    c: Vec3;
    c.x = a.x - b.x;
    c.y = a.y - b.y;
    c.z = a.z - b.z;
    return c;
}

This is a short example demonstrating vector subtraction:

a := Vec3.{1, 2, 3};
b := Vec3.{3, 4, 5};
c := a - b;
print("c = %\n", c);

Vector Negation

Here is how one can overload the negation operator for Vec3.

operator - :: (a: Vec3) -> Vec3 {
    b: Vec3;
    b.x = -a.x;
    b.y = -a.y;
    b.z = -a.z;
    return b;
}

This is a short example demonstrating vector negation:

a := Vec3.{1, 2, 3};
b := -a;
print("b = %\n", b);

Vector Scalar Multiplication

One can overload the multiplication operator so that Vec3 can support scalar multiplication. We can attach the #symmetric keyword to the function so that the scalar float value is swappable with the Vec3; in this way, we do not need to define two different functions to represent scalar multiplication.

operator * :: (a: Vec3, b: float) -> Vec3 #symmetric {
    c: Vec3 = a;
    c.x *= b;
    c.y *= b;
    c.z *= b;
    return c;
}

When we compile the example below, the ordering of the Vec3 and scalar float value does not need matter.

a: Vec3 = Vec3.{1, 2, 3};
b: float = 3.0;
c := a * b; 
d := b * a; // <- perform commutative scalar multiplication 
print("c = %\n", c);
print("d = %\n", d);

Vector Dot Product

Dot Product for Vec3 can be written as follows:

dot :: (a: Vec3, b: Vec3) -> float {
    c := (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
    return c;
}

This is a short example demonstrating dot product:

a := Vec3.{1, 2, 3};
b := Vec3.{2, 4, 6};
c := dot(a, b);
print("c = %\n", c); // <- answer should be 'c = 28.0'

Clone this wiki locally