Skip to content

Commit

Permalink
Nominal classes and methods (#722)
Browse files Browse the repository at this point in the history
Add support for nominal (or "named") classes with encapsulation. Inheritance will be in a later proposal. Here is an example of the proposed syntax:

```
class Circle {
  fn Create(c: Point, r: f32) -> Self {
    return {.center = c, .radius = r};
  }
  fn Diameter[me: Self]() -> f32 {
    return me.radius * 2;
  }
  fn Expand[addr me: Self*](distance: f32);

  private var center: Point;
  private var radius: f32;
}

fn Circle.Expand[addr me: Self*](distance: f32) {
  me->radius += distance;
}
```

Co-authored-by: Chandler Carruth <[email protected]>
  • Loading branch information
josh11b and chandlerc authored Aug 23, 2021
1 parent d71f5b1 commit 0820dec
Show file tree
Hide file tree
Showing 5 changed files with 769 additions and 89 deletions.
1 change: 1 addition & 0 deletions .codespell_ignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

circularly
copyable
crate
inout
pullrequest
statics
75 changes: 67 additions & 8 deletions docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Arrays and slices](#arrays-and-slices)
- [User-defined types](#user-defined-types)
- [Classes](#classes)
- [Assignment, copying](#assignment-copying)
- [Member access](#member-access)
- [Methods](#methods)
- [Allocation, construction, and destruction](#allocation-construction-and-destruction)
- [Assignment, copying, and moving](#assignment-copying-and-moving)
- [Moving](#moving)
- [Comparison](#comparison)
- [Implicit and explicit conversion](#implicit-and-explicit-conversion)
- [Inline type composition](#inline-type-composition)
Expand Down Expand Up @@ -599,8 +602,7 @@ fn RemoveLast(x: (Int, Int, Int)) -> (Int, Int) {

> References: [Classes](classes.md)
Classes are a way for users to define their own data strutures or named product
types.
Classes are a way for users to define their own data strutures or record types.

For example:

Expand All @@ -620,11 +622,7 @@ Breaking apart `Widget`:
- `Widget` has one `String` member: `payload`.
- Given an instance `dial`, a member can be referenced with `dial.paylod`.

##### Allocation, construction, and destruction

> **TODO:** Needs a feature design and a high level summary provided inline.
##### Assignment, copying, and moving
##### Assignment, copying

You may use a _structural data class literal_, also known as a _struct literal_,
to assign or initialize a variable with a class type.
Expand All @@ -641,6 +639,67 @@ var thingy: Widget = sprocket;
sprocket = thingy;
```

##### Member access

The data members of a variable with a class type may be accessed using dot `.`
notation:

```carbon
Assert(sprocket.x == thingy.x);
```

##### Methods

Class type definitions can include methods:

```carbon
class Point {
fn Distance[me: Self](x2: i32, y2: i32) -> f32 {
var dx: i32 = x2 - me.x;
var dy: i32 = y2 - me.y;
return Math.Sqrt(dx * dx - dy * dy);
}
fn Offset[addr me: Self*](dx: i32, dy: i32);
var x: i32;
var y: i32;
}
fn Point.Offset[addr me: Self*](dx: i32, dy: i32) {
me->x += dx;
me->y += dy;
}
var origin: Point = {.x = 0, .y = 0};
Assert(Math.Abs(origin.Distance(3, 4) - 5.0) < 0.001);
origin.Offset(3, 4);
Assert(origin.Distance(3, 4) == 0.0);
```

This defines a `Point` class type with two integer data members `x` and `y` and
two methods `Distance` and `Offset`:

- Methods are defined as functions with a `me` parameter inside square
brackets `[`...`]` before the regular explicit parameter list in parens
`(`...`)`.
- Methods are called using using the member syntax, `origin.Distance(`...`)`
and `origin.Offset(`...`)`.
- `Distance` computes and returns the distance to another point, without
modifying the `Point`. This is signified using `[me: Self]` in the method
declaration.
- `origin.Offset(`...`)` does modify the value of `origin`. This is signified
using `[addr me: Self*]` in the method declaration.
- Methods may be declared lexically inline like `Distance`, or lexically out
of line like `Offset`.

##### Allocation, construction, and destruction

> **TODO:** Needs a feature design and a high level summary provided inline.
##### Moving

> **TODO:** Needs a feature design and a high level summary provided inline.
##### Comparison

> **TODO:** Needs a feature design and a high level summary provided inline.
Expand Down
Loading

0 comments on commit 0820dec

Please sign in to comment.