0

Recently, I've been learning a bit more of C++ and the dangers and uses of operator overloading, and the readability boost it provides to arithmetic types (like Complex numbers).

A while ago, I was playing around with Rust, and I really liked how they handled operator overloading, that is, via Traits in the std::ops crate. So, having:

struct Fraction {
  numerator: i32,
  denominator: i32,
}

impl Add for Fraction { /* ... */ }

Ends up overloading the + operator. This leads me to wonder the subject of the title...

Can Java implement a limited set of operator overloading via Interfaces? The compiler could check if the caller class implements the interface for a given operator, and change the operator to a method call (thus, it all being syntax sugar) or fail compiling otherwise.

Would this imply breaking changes for code compiled in older versions? Anyone know if this has been already discussed in mailings list, or a JEP proposed?

Alxe
  • 113

2 Answers2

7

The answer to your question is rather simple: Backwards-compatibility means not changing the meaning of existing code. Since there is no existing code using user-defined operators, because user-defined operators do not exist, introducing them cannot possibly break backwards-compatibility.

Foo a = new Foo();
Foo b = new Foo();

Foo c = a + b;

Such code just can't be written today.

The simplest implementation of operator overloading would be to just make them methods. E.g.

class Fraction {
  int numerator, denominator;

  public Fraction *(Fraction other) {
    return new Fraction(numerator * other.numerator, denominator * other.denominator);
  }
}

Since those names are currently illegal, backwards-compatibility is preserved: there is no code currently which uses these names and whose meaning could change. If you implement a name-mangling scheme for those methods, you could even get by without changing the bytecode and classfile formats, so code that is compiled with a JavaXYZ compiler will still run on Java 8.

This is the simplest possible solution. If you want something more sophisticated, like defining the fixity, associativity and precedence of operators, you will have to do more work. In particular, parsing is (somewhat) complicated: you have to know whether is left-associatice or right-associative before you can parse a ∪ b ∪ c correctly, for example. So you have to analyze the imported operator definitions before you can parse the code.

Jörg W Mittag
  • 104,619
1

It would break existing code if you could override == comparison, or even = assignment. == is used to compare the memory addresses of two objects, independent of what their equals() method says. == is even true for two null objects. I don’t want to imagine what happens if objects are allowed to override = assignment operator.