LEVIATHAN v962456e · 962456eee1

Expressions

Operators on objects

A class defines the meaning of an operator by declaring a member with a symbolic selector; the equality operator derives its negation automatically.

since 0.1.0-alpha.1linuxwindowswasm

Description

For a op b where a is an object, the compiler looks up the member named (op) on a's class and picks the overload that fits the type of b. A class may declare several overloads of one operator for different right-hand types.

An operator is declared as a member with a symbolic selector in parentheses: Money (+)(Money other) => ...;, bool (==)(Money other) => ...;.

(==) must return bool. You never write (!=) yourself: a != b is derived as !(a == b).

Operator members

class Money {
    int cents;
    Money (+)(Money other) => Money(cents + other.cents);
    bool (==)(Money other) => cents == other.cents;
    bool (<)(Money other) => cents < other.cents;
    string toString() => "${cents} cents";
}

Money a = Money(150);
Money b = Money(250);
console.writeln((a + b).toString());
console.writeln(a == Money(150));
console.writeln(a != b);
console.writeln(a != Money(150));
console.writeln(a < b);
400 cents
true
true
false
true

Rules

  • The operator member is chosen on the type of the left operand, and the overload on the type of the right operand.
  • (==) must return bool.
  • != is derived from == as its negation. Declaring only (==) is enough.
  • The same operator can be both a built-in operation and a user operation: + adds two int values and also calls a class's (+). Which one applies depends on the operand types.
  • A binary operator used on an object whose class declares no matching member is a runtime failure: it throws a RuntimeException ("no operator '+' on 'Plain'") that can be caught.

Examples

class Money {
    int cents;
    Money (+)(Money other) => Money(cents + other.cents);
    Money (+)(int extra) => Money(cents + extra);
    string toString() => "${cents} cents";
}

Money a = Money(150);
console.writeln((a + Money(100)).toString());   // 250 cents
console.writeln((a + 5).toString());            // 155 cents
not run — blocked by an open compiler bug
class Plain {
    int v = 1;
}

Plain p = Plain();
try {
    console.writeln(p + p);
} catch (RuntimeException e) {
    console.writeln("caught: ${e.message}");
}
// caught: no operator '+' on 'Plain'
not run — blocked by an open compiler bug

Notes

Indexing with [] is declared the same way, with the selector ([]). See lang.indexing.

See also

  • int — The signed 64-bit integer type, the default type of whole numbers.
  • Indexing — The square-bracket operator reads and writes elements through an indexer accessor, and rebinds the variable when the target is an array.