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

Generics details 2: adapters, associated types, parameterized interfaces #731

Merged
merged 38 commits into from
Sep 5, 2021
Merged
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9e996e1
Filling out template with PR 731
josh11b Aug 11, 2021
e961002
Start proposal text
josh11b Aug 11, 2021
9199bf7
Fill in details
josh11b Aug 11, 2021
6887a70
Start on changes to overview
josh11b Aug 11, 2021
c7f8b90
Working on the overview
josh11b Aug 11, 2021
8f6b276
Checkpoint progress.
josh11b Aug 11, 2021
6d05344
Complete first draft of overview
josh11b Aug 11, 2021
f6341ca
Should `let` use `:!` for compile-time constants?
josh11b Aug 11, 2021
2487aca
let for associated constants uses `:!`
josh11b Aug 11, 2021
90c3f59
Rejected deduced interface params
josh11b Aug 11, 2021
de8408f
Value patterns rejected alternative
josh11b Aug 11, 2021
3fc2e6d
Define associated item
josh11b Aug 12, 2021
0977043
Link to terminology
josh11b Aug 12, 2021
66a5173
Associated functions -> associated class functions
josh11b Aug 12, 2021
5ba4d7f
Associated type fulfilled by member type
josh11b Aug 12, 2021
84da573
Update open questions
josh11b Aug 13, 2021
b9689c8
Reflect decision on #739, resolve proposal TODOs
josh11b Aug 18, 2021
a092945
Apply suggestions from code review
josh11b Aug 18, 2021
510c088
Fix formatting
josh11b Aug 18, 2021
a39fbf6
Redo deduction limits to address feedback
josh11b Aug 20, 2021
7c71e49
Add example to interface params
josh11b Aug 20, 2021
e5389d2
Less confusing terminology re: type parameters
josh11b Aug 27, 2021
2095567
Non-type interface parameters
josh11b Aug 27, 2021
2c75fda
Apply suggestions from code review
josh11b Sep 1, 2021
115af6f
Follow ups from review suggestions
josh11b Sep 1, 2021
af12ceb
singleton_type -> singleton_type_of
josh11b Sep 1, 2021
a14c8a4
Haskell newtype
josh11b Sep 1, 2021
d29afc8
Terser syntax question
josh11b Sep 1, 2021
db935d4
Implement suggestion
josh11b Sep 1, 2021
e3a519b
Apply suggestions from code review
josh11b Sep 1, 2021
ef71709
Delete non-type generic future work
josh11b Sep 1, 2021
c0eeeb8
Update proposals/p0731.md
josh11b Sep 1, 2021
f70fcc8
Associated item -> entity
josh11b Sep 1, 2021
3c6919f
Rationale for "adapter" over "adaptor"
josh11b Sep 3, 2021
0d1bfcb
Apply suggestions from code review
josh11b Sep 3, 2021
e3d9d28
No implicit conversion for adapter extends
josh11b Sep 3, 2021
b9554ea
Merge remote-tracking branch 'upstream/trunk' into details
josh11b Sep 3, 2021
1569940
Not only associated types rationale
josh11b Sep 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Complete first draft of overview
  • Loading branch information
josh11b committed Aug 11, 2021
commit 6d05344fbafca9cb2c3b1c0aec4721e5686fe3ff
64 changes: 48 additions & 16 deletions docs/design/generics/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -470,22 +470,42 @@ At that point, two erasures occur:

### Adapting types

FIXME: A "newtype" mechanism called "adapting types" may be provided to create
new types that are compatible with existing types but with different interface
implementations. This could be used to add or replace implementations, or define
implementations for reuse.
Carbon has a mechanism called "adapting types" to create new types that are
compatible with existing types but with different interface implementations.
This could be used to add or replace implementations, or define implementations
for reuse.

In this example, we have multiple ways of sorting a collection of `Song` values.

```
class Song { ... }

adapter SongByArtist extends Song {
impl as Comparable { ... }
}

adapter SongByTitle extends Song {
impl as Comparable { ... }
}
```

Values of type `Song` may be cast to `SongByArtist` or `SongByTitle` to get a
specific sort order.

### Type parameters

FIXME: Associated types and interface parameters will be provided to allow
function signatures to vary with the implementing type. The biggest difference
between these is that associated types ("output types") may be deduced from a
type, and types can implement the same interface multiple times with different
interface parameters ("input types").
Associated types and interface parameters allow function signatures to vary with
the implementing type. The biggest difference between these is that associated
types ("output types") may be deduced from a type, and types can implement the
same interface multiple times with different interface parameters ("input
types").

#### Associated types

FIXME
Expect type parameters to be associated types by default. Since associated types
may be deduced, they are more convenient to use. Imagine we have a `Stack`
josh11b marked this conversation as resolved.
Show resolved Hide resolved
interface. Different types implementing `Stack` will have different element
types:

```
interface Stack {
Expand All @@ -501,9 +521,20 @@ implement `Stack` give `ElementType` a specific value of some type implementing
`Movable`. Functions that accept a type implementing `Stack` can deduce the
`ElementType` from the stack type.

```
// ✅ This is allowed, since the type of the stack will determine
// `ElementType`.
fn PeekAtTopOfStack[StackType:! Stack](s: StackType*)
-> StackType.ElementType;
```

#### Parameterized interfaces

FIXME
Parameterized interfaces are commonly associated with overloaded operators.
Imagine we have an interface for determining if two values are equivalent, and
josh11b marked this conversation as resolved.
Show resolved Hide resolved
we want to allow those types to be different. An element in a hash map might
have type `Pair(String, i64)` that implements both `Equatable(String)` and
`Equatable(Pair(String, i64))`.

```
interface Equatable(T:! Type) {
Expand All @@ -515,16 +546,17 @@ interface Equatable(T:! Type) {
multiple times as long as each time it is with a different value of the `T`
parameter. Functions may accept types implementing `Equatable(i32)` or
`Equatable(f32)`. Functions can't accept types implementing `Equatable(T)` in
general, without some other parameter that can determine `T`.
general, unless some other parameter determines `T`.

```
// ✅ This is allowed, since the `T` parameter is determined by the `v`
// parameter.
// ✅ This is allowed, since the value of `T` is determined by the
// `v` parameter.
fn FindInVector[T:! Type, U:! Equatable(T)](v: Vector(T), needle: U)
-> Optional(i32);

// ❌ This is forbidden, since `U` could implement `Equatable` multiple
// times, there is no way to determine the value for `T`.
// ❌ This is forbidden. Since `U` could implement `Equatable`
// multiple times, there is no way to determine the value for `T`.
// Contrast with `PeekAtTopOfStack` in the associated type example.
fn CompileError[T:! Type, U:! Equatable(T)](x: U) -> T;
```

Expand Down