Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework operator interfaces #1178

Merged
merged 10 commits into from
May 3, 2022
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