Programing Language Design: Why You Need Operators

By Xah Lee. Date: .

Why do we Need Operators in programing language? And why is it good if a programing language allows you to define your own operators?

In scientific programing, you have to deal with math formulas often. Math formula in traditional programing language notation is not readable.

Here is a quadratic formula in normal math notation:

quadratic formula 2022-01-18
quadratic formula

Here is functional notation in programing languages:

assign(x, div( plus(-b, sqrt( plus( power(b, 2), neg(times(4, a, c))))), times(2, a)))

If we allow symbols in function names, we have:

=(x, /( +(-b, √( +( ^(b, 2), -(*(4, a, c))))), *(2, a)))

in Lisp notation:

(set x (div (plus (neg b) (sqrt (power b 2) (neg (times 4 a c)))) (times 2 a )))

if we allow symbols, we have:

(= x (/ (+ (- b) (√ (^ b 2) (- (* 4 a c)))) (* 2 a )))

If we allow defining operators, we have the normal infix notation:

x = (-b + √(b^2 - 4 * a * c) ) / (2 * a)

If we allow space as implicit multiplication, we have the the shortest notation and most readable:

x = (-b + √(b^2 - 4 a c) ) / (2 a)

This is why operators in programing languages is essential for high-level programing languages in scientific programing.

Now, should programing language allow users to define their own operators?

In programing, the datatypes are often arbitrarily defined by user, so you need to define your own operators such matrix multiplication and vector addition.

Here's real world example in JavaScript working and matrix and vectors, using function notation and not allowing math symbols in names:

const svg_ellipse_arc = (([cx,cy],[rx,ry], [θ, Δ], φ ) => {
Δ = Δ % (2*π);
const rotMatrix = rotate_matrix (φ);
const [sX, sY] = vec_add ( matrix_times ( rotMatrix, [rx * cos(θ),ry * sin(θ)] ), [cx,cy] ) ;
const [eX, eY] = vec_add ( matrix_times ( rotMatrix, [rx * cos(θ+Δ),ry * sin(θ+Δ)] ), [cx,cy] ) ;
const fA = ( ( Math.abs (Δ) > π ) ? 1 : 0 );
const fS = ( ( Δ > 0 ) ? 1 : 0 );
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", "M " + sX + " " + sY + " A " + [ rx , ry , φ/π*180 , fA, fS, eX, eY ].join(" "));
return path;
});

Now, if we allow math symbols in names, we have:

const svg_ellipse_arc = (([cx,cy],[rx,ry], [θ, Δ], φ ) => {
Δ = Δ % (2*π);
const rotMatrix = rotate_matrix (φ);
const [sX, sY] = ⊕( ⊗( rotMatrix, [rx * cos(θ),ry * sin(θ)] ), [cx,cy] ) ;
const [eX, eY] = ⊕( ⊗( rotMatrix, [rx * cos(θ+Δ),ry * sin(θ+Δ)] ), [cx,cy] ) ;
const fA = ( ( Math.abs (Δ) > π ) ? 1 : 0 );
const fS = ( ( Δ > 0 ) ? 1 : 0 );
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", "M " + sX + " " + sY + " A " + [ rx , ry , φ/π*180 , fA, fS, eX, eY ].join(" "));
return path;
});

Now, if we can define operators with math symbols in names, we have:

const svg_ellipse_arc = (([cx,cy],[rx,ry], [θ, Δ], φ ) => {
Δ = Δ % (2*π);
const rotMatrix = rotate_matrix (φ);
const [sX, sY] = rotMatrix ⊗ [rx * cos(θ),ry * sin(θ)] ⊕ [cx,cy];
const [sX, sY] = rotMatrix ⊗ [rx * cos(θ+Δ),ry * sin(θ+Δ)] ⊕ [cx,cy];
const fA = ( ( Math.abs (Δ) > π ) ? 1 : 0 );
const fS = ( ( Δ > 0 ) ? 1 : 0 );
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", "M " + sX + " " + sY + " A " + [ rx , ry , φ/π*180 , fA, fS, eX, eY ].join(" "));
return path;
});

Programing Language Operators