Limited operator overloading

  1. struct Vec {
  2. x int
  3. y int
  4. }
  5. fn (a Vec) str() string {
  6. return '{$a.x, $a.y}'
  7. }
  8. fn (a Vec) + (b Vec) Vec {
  9. return Vec{a.x + b.x, a.y + b.y}
  10. }
  11. fn (a Vec) - (b Vec) Vec {
  12. return Vec{a.x - b.x, a.y - b.y}
  13. }
  14. fn main() {
  15. a := Vec{2, 3}
  16. b := Vec{4, 5}
  17. mut c := Vec{1, 2}
  18. println(a + b) // "{6, 8}"
  19. println(a - b) // "{-2, -2}"
  20. c += a
  21. println(c) // "{3, 5}"
  22. }

Operator overloading goes against V’s philosophy of simplicity and predictability. But since scientific and graphical applications are among V’s domains, operator overloading is an important feature to have in order to improve readability:

a.add(b).add(c.mul(d)) is a lot less readable than a + b + c * d.

To improve safety and maintainability, operator overloading is limited:

  • It’s only possible to overload +, -, *, /, %, <, >, ==, !=, <=, >= operators.
  • == and != are self generated by the compiler but can be overridden.
  • Calling other functions inside operator functions is not allowed.
  • Operator functions can’t modify their arguments.
  • When using < and == operators, the return type must be bool.
  • !=, >, <= and >= are auto generated when == and < are defined.
  • Both arguments must have the same type (just like with all operators in V).
  • Assignment operators (*=, +=, /=, etc) are auto generated when the corresponding operators are defined and operands are of the same type.