Skip to content

Commit

Permalink
Rework operator interfaces (#1178)
Browse files Browse the repository at this point in the history
Add concrete design for interfaces for comparison.

Rename interfaces for arithmetic following current thinking in #1058.

Update rules for mixed-type comparisons for data classes following #710.

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
  • Loading branch information
zygoloid and chandlerc authored May 3, 2022
1 parent f42ca04 commit 4a8ca9c
Show file tree
Hide file tree
Showing 4 changed files with 400 additions and 53 deletions.
62 changes: 31 additions & 31 deletions docs/design/expressions/arithmetic.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,77 +182,75 @@ following family of interfaces:

```
// Unary `-`.
interface Negatable {
interface Negate {
let Result:! Type = Self;
fn Negate[me: Self]() -> Result;
fn Op[me: Self]() -> Result;
}
```

```
// Binary `+`.
interface AddableWith(U:! Type) {
interface AddWith(U:! Type) {
let Result:! Type = Self;
fn Add[me: Self](other: U) -> Result;
fn Op[me: Self](other: U) -> Result;
}
constraint Addable {
extends AddableWith(Self) where .Result = Self;
constraint Add {
extends AddWith(Self) where .Result = Self;
}
```

```
// Binary `-`.
interface SubtractableWith(U:! Type) {
interface SubWith(U:! Type) {
let Result:! Type = Self;
fn Subtract[me: Self](other: U) -> Result;
fn Op[me: Self](other: U) -> Result;
}
constraint Subtractable {
extends SubtractableWith(Self) where .Result = Self;
constraint Sub {
extends SubWith(Self) where .Result = Self;
}
```

```
// Binary `*`.
interface MultipliableWith(U:! Type) {
interface MulWith(U:! Type) {
let Result:! Type = Self;
fn Multiply[me: Self](other: U) -> Result;
fn Op[me: Self](other: U) -> Result;
}
constraint Multipliable {
extends MultipliableWith(Self) where .Result = Self;
constraint Mul {
extends MulWith(Self) where .Result = Self;
}
```

```
// Binary `/`.
interface DividableWith(U:! Type) {
interface DivWith(U:! Type) {
let Result:! Type = Self;
fn Divide[me: Self](other: U) -> Result;
fn Op[me: Self](other: U) -> Result;
}
constraint Dividable {
extends DividableWith(Self) where .Result = Self;
constraint Div {
extends DivWith(Self) where .Result = Self;
}
```

```
// Binary `%`.
interface ModuloWith(U:! Type) {
interface ModWith(U:! Type) {
let Result:! Type = Self;
fn Mod[me: Self](other: U) -> Result;
fn Op[me: Self](other: U) -> Result;
}
constraint Modulo {
extends ModuloWith(Self) where .Result = Self;
constraint Mod {
extends ModWith(Self) where .Result = Self;
}
```

Given `x: T` and `y: U`:

- The expression `-x` is rewritten to `x.(Negatable.Negate)()`.
- The expression `x + y` is rewritten to `x.(AddableWith(U).Add)(y)`.
- The expression `x - y` is rewritten to
`x.(SubtractableWith(U).Subtract)(y)`.
- The expression `x * y` is rewritten to
`x.(MultipliableWith(U).Multiply)(y)`.
- The expression `x / y` is rewritten to `x.(DividableWith(U).Divide)(y)`.
- The expression `x % y` is rewritten to `x.(ModuloWith(U).Mod)(y)`.
- The expression `-x` is rewritten to `x.(Negate.Op)()`.
- The expression `x + y` is rewritten to `x.(AddWith(U).Op)(y)`.
- The expression `x - y` is rewritten to `x.(SubWith(U).Op)(y)`.
- The expression `x * y` is rewritten to `x.(MulWith(U).Op)(y)`.
- The expression `x / y` is rewritten to `x.(DivWith(U).Op)(y)`.
- The expression `x % y` is rewritten to `x.(ModWith(U).Op)(y)`.

Implementations of these interfaces are provided for built-in types as necessary
to give the semantics described above.
Expand All @@ -278,4 +276,6 @@ to give the semantics described above.
## References

- Proposal
[#1083: arithmetic](https://github.com/carbon-language/carbon-lang/pull/1083).
[#1083: Arithmetic](https://github.com/carbon-language/carbon-lang/pull/1083)
- Proposal
[#1178: Rework operator interfaces](https://github.com/carbon-language/carbon-lang/pull/1178)
2 changes: 1 addition & 1 deletion docs/design/expressions/as_expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ unordered with respect to binary arithmetic, bitwise operators, and unary `not`.

```
// OK
var x: i32* as Comparable;
var x: i32* as Eq;
// OK, `x as (U*)` not `(x as U)*`.
var y: auto = x as U*;
Expand Down
Loading

0 comments on commit 4a8ca9c

Please sign in to comment.