1960s The
ALGOL 68 specification allowed operator overloading. Extract from the ALGOL 68 language specification (page 177) where the overloaded operators ¬, =, ≠, and
abs are defined: 10.2.2. Operations on Boolean Operands a)
op ∨ = (
bool a, b)
bool:( a |
true | b ); b)
op ∧ = (
bool a, b)
bool: ( a | b |
false ); c)
op ¬ = (
bool a)
bool: ( a |
false |
true ); d)
op = = (
bool a, b)
bool:( a∧b ) ∨ ( ¬b∧¬a ); e)
op ≠ = (
bool a, b)
bool: ¬(a=b); f)
op abs = (
bool a)
int: ( a | 1 | 0 ); Note that no special declaration is needed to
overload an operator, and the programmer is free to create new operators. For dyadic operators their priority compared to other operators can be set:
prio max = 9;
op max = (
int a, b)
int: ( a>b | a | b );
op ++ = (
ref int a )
int: ( a +:= 1 );
1980s Ada supports overloading of operators from its inception, with the publication of the Ada 83 language standard. However, the language designers chose to preclude the definition of new operators. Only extant operators in the language may be overloaded, by defining new functions with identifiers such as "+", "*", "&" etc. Subsequent revisions of the language (in 1995 and 2005) maintain the restriction to overloading of extant operators. In
C++, operator overloading is more refined than in
ALGOL 68.
1990s Java language designers at
Sun Microsystems chose to omit overloading. When asked about operator overloading, Brian Goetz of
Oracle responded "
Value types first, then we can talk about it.", suggesting that it could potentially be added after
Project Valhalla.
Python allows operator overloading through the implementation of methods with special names. For example, the addition (+) operator can be overloaded by implementing the method .
Ruby allows operator overloading as syntactic sugar for simple method calls.
Lua allows operator overloading as syntactic sugar for method calls with the added feature that if the first operand doesn't define that operator, the method for the second operand will be used.
2000s Microsoft added operator overloading to
C# in 2001 and to
Visual Basic .NET in 2003. C# operator overloading is very similar in syntax to C++ operator overloading: public class Fraction { private int numerator; private int denominator; // ... public static Fraction operator +(Fraction lhs, Fraction rhs) => new Fraction(lhs.numerator * rhs.denominator + rhs.numerator * lhs.denominator, lhs.denominator * rhs.denominator); }
Scala treats all operators as methods and thus allows operator overloading by proxy.
2010s In
Raku, the definition of all operators is delegated to lexical functions, and so, using function definitions, operators can be overloaded or new operators added. For example, the function defined in the
Rakudo source for incrementing a Date object with "+" is: multi infix:(Date:D $d, Int:D $x) { Date.new-from-daycount($d.daycount + $x) } Since "multi" was used, the function gets added to the list of
multidispatch candidates, and "+" is only overloaded for the case where the type constraints in the function signature are met. While the capacity for overloading includes +, *, >=, the
postfix and term i, and so on, it also allows for overloading various brace operators: [x, y], x[y], x{y}, and x(y).
Kotlin has supported operator overloading since its creation by overwriting specially named functions (like plus(), inc(), rangeTo(), etc.) data class Point(val x: Int, val y: Int) { operator fun plus(other: Point): Point { return Point(this.x + other.x, this.y + other.y) } } Because both Kotlin and Java compile to Java class file|, when converted back to
Java this will just be represented as: public class Point { // fields and constructor... public Point plus(Point other) { return new Point(this.x + other.x, this.y + other.y); } } Operator overloading in
Rust is accomplished by implementing the
traits in std::ops. use std::ops::Add; • [derive(Debug)] struct Point { x: i32, y: i32 } impl Point { pub fn new(x: i32, y: i32) -> Self { Point {x, y} } } impl Add for Point { type Output = Point; fn add(self, other: Point) -> Point { Point { x: self.x + other.y, y: self.y + other.y } } } fn main() { let p1: Point = Point::new(1, 2); let p2: Point = Point::new(3, 4); let sum: Point = p1 + p2; println!("Sum of p1 and p2: {:?}", sum); } ==See also==