Skip to content

Commit

Permalink
Basic classes: use cases, struct literals, struct types, and future w…
Browse files Browse the repository at this point in the history
…ork (#561)

This proposal defines the very basics of `class` types, primarily focused on:

-   use cases including: data classes, encapsulated types, inheritance with and without `virtual`, interfaces as base classes, and mixins for code reuse;
-   anonymous data types for called _structural data classes_ or _struct types_. Struct literals are used to initialize class values and ad-hoc parameter and return types with named components; and
-   future work, including the provisional syntax already in use for features that have not been decided.

The intent is to both make some small incremental progress and get agreement on direction. As such it doesn't include things like nominal types, methods, access control, inheritance, etc.

It proposes this struct type and literal syntax:
```
var p: {.x: Int, .y: Int} = {.x = 0, .y = 1};
```
Note that it uses commas (`,`) between fields instead of semicolons (`;`), and no introducer for types or literal values.

Incorporates decisions from #665 , #653 , #651


Co-authored-by: Geoff Romer <[email protected]>
Co-authored-by: Chandler Carruth <[email protected]>
  • Loading branch information
3 people authored Aug 9, 2021
1 parent deb1981 commit febf880
Show file tree
Hide file tree
Showing 9 changed files with 1,217 additions and 173 deletions.
72 changes: 23 additions & 49 deletions docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Pointers and references](#pointers-and-references)
- [Arrays and slices](#arrays-and-slices)
- [User-defined types](#user-defined-types)
- [Structs](#structs)
- [Classes](#classes)
- [Allocation, construction, and destruction](#allocation-construction-and-destruction)
- [Assignment, copying, and moving](#assignment-copying-and-moving)
- [Comparison](#comparison)
Expand Down Expand Up @@ -170,14 +170,14 @@ cleaned up during evolution.
Name paths in Carbon always start with the package name. Additional namespaces
may be specified as desired.
For example, this code declares a struct `Geometry.Shapes.Flat.Circle` in a
For example, this code declares a class `Geometry.Shapes.Flat.Circle` in a
library `Geometry/OneSide`:
```carbon
package Geometry library("OneSide") namespace Shapes;
namespace Flat;
struct Flat.Circle { ... }
class Flat.Circle { ... }
```

This type can be used from another package:
Expand Down Expand Up @@ -487,7 +487,7 @@ fn Sum(a: Int, b: Int) -> Int {
## Types

> References: [Primitive types](primitive_types.md), [tuples](tuples.md), and
> [structs](structs.md)
> [classes](classes.md)
>
> **TODO:** References need to be evolved.
Expand Down Expand Up @@ -595,19 +595,17 @@ fn RemoveLast(x: (Int, Int, Int)) -> (Int, Int) {
### User-defined types

#### Structs
#### Classes

> References: [Structs](structs.md)
>
> **TODO:** References need to be evolved.
> References: [Classes](classes.md)
`struct`s 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 named product
types.

For example:

```carbon
struct Widget {
class Widget {
var x: Int;
var y: Int;
var z: Int;
Expand All @@ -622,50 +620,26 @@ Breaking apart `Widget`:
- `Widget` has one `String` member: `payload`.
- Given an instance `dial`, a member can be referenced with `dial.paylod`.

More advanced `struct`s may be created:
##### Allocation, construction, and destruction

```carbon
struct AdvancedWidget {
// Do a thing!
fn DoSomething(self: AdvancedWidget, x: Int, y: Int);
> **TODO:** Needs a feature design and a high level summary provided inline.
// A nested type.
struct Nestedtype {
// ...
}
##### Assignment, copying, and moving

private var x: Int;
private var y: Int;
}
You may use a _structural data class literal_, also known as a _struct literal_,
to assign or initialize a variable with a class type.

fn Foo(thing: AdvancedWidget) {
thing.DoSomething(1, 2);
}
```carbon
var sprocket: Widget = {.x = 3, .y = 4, .z = 5, .payload = "Sproing"};
sprocket = {.x = 2, .y = 1, .z = 0, .payload = "Bounce"};
```

Breaking apart `AdvancedWidget`:

- `AdvancedWidget` has a public object method `DoSomething`.
- `DoSomething` explicitly indicates how the `AdvancedWidget` is passed to
it, and there is no automatic scoping - `self` must be specified as the
first input. The `self` name is also a keyword that explains how to
invoke this method on an object.
- `DoSomething` accepts `AdvancedWidget` _by value_, which is easily
expressed here along with other constraints on the object parameter.
- `AdvancedWidget` has two private data members: `x` and `y`.
- Private methods and data members are restricted to use by
`AdvancedWidget` only, providing a layer of easy validation of the most
basic interface constraints.
- `Nestedtype` is a nested type, and can be accessed as
`AdvancedWidget.Nestedtype`.

##### Allocation, construction, and destruction

> **TODO:** Needs a feature design and a high level summary provided inline.
##### Assignment, copying, and moving
You may also copy one struct into another of the same type.

> **TODO:** Needs a feature design and a high level summary provided inline.
```carbon
var thingy: Widget = sprocket;
sprocket = thingy;
```

##### Comparison

Expand Down Expand Up @@ -818,7 +792,7 @@ be used to instantiate the parameterized definition with the provided arguments
in order to produce a complete type. For example:

```carbon
struct Stack(T:$$ Type) {
class Stack(T:$$ Type) {
var storage: Array(T);
fn Push(value: T);
Expand Down
Loading

0 comments on commit febf880

Please sign in to comment.