16730, “lydia-duncan”, “Should operators be defined as methods on types instead of stand-alone functions?”, “2020-11-17T19:42:55Z”
This has come to mind as a result of the questions posed by #16725 and #16727, but we have toyed with it in passing before.
Checking a subset of languages that allow operator overloading, it looks like:
- C++ allows defining operators as both methods (
R K::operator +(S b);
within the type definition of K) and stand-alone functions (R operator +(K a, S b);
. - Python allows defining operators as methods (
__add__(self, other)
) - Rust has a list of traits that expect method definitions within their context. So you connect the trait to the type and then define the necessary method (see this link for a better explanation)
- Near as I can tell, Julia allows defining operators as functions (
Base.:+(x::SomeType, y::SomeType) = ...
) - It seems like D allows defining operators as methods, though the docs says “functions” - it may be I don’t know enough about D and functions and methods are not distinguishable there (see this link)
Pros:
- Ties the operator to the type(s) it operates on more closely
- Would make the implementation to access operators defined in the same location as a type when the type’s scope is not otherwise visible trivial (as we already resolve methods by jumping to that scope)
Cons:
- For operators that take multiple arguments, choosing which one to define it on is kinda arbitrary and can lead to confusion when trying to access operators defined outside the scope where the type is defined
- Will require changing a lot of code
- Special handling to treat them similarly to methods in the compiler today would be replaced by special handling to not treat them similarly in other cases (for instance, it seems like we wouldn’t want forwarding to apply to operators, see #11717)