Rework operator interfaces
[Pull request](https://github.com/carbon-language/carbon-lang/pull/1178
Table of contents
Problem
Our operator interface names need to be updated to match the decision in #1058. Further, we are missing a description of the interfaces used to overload comparison operators, and the rules are not up to date with the decision in #710.
Background
See the two leads issues for background and discussion of options.
Proposal
See changes to the design.
Details
Beyond establishing names for interfaces, this proposal also establishes:
- We will have high-level interfaces for equality and relational comparison. The equality interface provides both
==
and!=
. The relational comparison interface provides all of<
,<=
,>
, and>=
. - Following the convention established for arithmetic operators, we provide both a heterogeneous comparison interface and a homogeneous constraint. For example,
T is EqWith(T)
is equivalent toT is Eq
. - The high-level interfaces always return
bool
. - The high-level interfaces have expected semantics associated with them.
It is intended that we also provide low-level interfaces, to directly control individual operators and to allow a result type other than bool
. These are not included in this proposal, as it’s not yet clear how they should be specified, and it’s more important to get the high-level interfaces decided at this point.
Rationale
- Language tools and ecosystem
- High-level semantics allow tools to reason about the intended meaning of Carbon code. For example, a tool could statically or dynamically determine that an implementation of
Ordered
doesn’t satisfy the expected rules and produce a warning.
- High-level semantics allow tools to reason about the intended meaning of Carbon code. For example, a tool could statically or dynamically determine that an implementation of
- Performance-critical software
- We expect
==
and ordering to be customized separately, in order to avoid cases where a suboptimal==
is constructed in terms of an ordering. See C++ committee paper P1190R0 for details on the problem.
- We expect
- Code that is easy to read, understand, and write
- Combining all comparison operators of the same kind – equality or relational – into a single interface makes it both easier to implement them and easier to write a generic constraint for them. This approach is also expected to be easy to teach, with the low-level interfaces only explained to a more advanced audience.
- Practical safety and testing mechanisms
- While there are rules for the comparison interfaces, violating those rules does not result in immediate unbounded undefined behavior. However, implementations should still attempt to detect violations of these rules and report them where that is feasible.
- Interoperability with and migration from existing C++ code
- The intent to provide a low-level interface for individual operators is directly motivated by the desire to provide strong interoperability with operators defined in C++. While this functionality is not part of this proposal, it’s expected to follow once the interactions with generics are worked out.
Alternatives considered
Use ComparableWith
instead of OrderedWith
We could use the term “comparable” for relational comparisons instead of “ordered”. There is existing practice for both: for example, Rust and Haskell use Ord
, and Swift uses Comparable
.
The main argument for using “ordered” instead of “comparable” is that ==
and !=
are also a form of comparison but aren’t part of OrderedWith
, and the word “ordered” distinguishes relational comparison from equality comparison.