mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:41:27 +01:00
Generics details part 1 (#553)
This proposal goes into the details of the core of the generics feature, to achieve the goals from #24 , and provides an outline covering future work. It has been summarized in these presentations: - [basic usage](https://docs.google.com/presentation/d/1OZiMTVW2Ommop5WTs9RyEwnGxy9yzaAPF7Cj5KUfDsY/edit?resourcekey=0-Nya0Soz3ZNs3hJan8VIrTA#slide=id.p) - [details: interfaces](https://docs.google.com/presentation/d/1FSlqtE5hXZIwOO52UrAK9DINBLDWtgu24dugHfomUMg/edit#slide=id.p) - [details: facet types](https://docs.google.com/presentation/d/17KG0TeJ4OChMRdLJPS8TE_K6SoL4lFy1FUGr2CDzX-A/edit?resourcekey=0-kLnZqd5NrbGSwmbunTyB-A#slide=id.p) - [details: type-types](https://docs.google.com/presentation/d/1Hn3VDlVjwhjx3SKM2KXKE7lW208nXff30x3-uIO4_Fo/edit#slide=id.p) - [details: extending/refining interfaces](https://docs.google.com/presentation/d/1K0cCHeb9JTJY9QCGEVO9CcJNHYlaXkoPESv4J9tl5LU/edit#slide=id.p) Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
committed by
GitHub
co-authored by
Richard Smith
parent
d5564280ab
commit
ecb5a611e5
@@ -16,5 +16,6 @@ feature of Carbon:
|
||||
direction.
|
||||
- [Terminology](terminology.md) - A glossary establishing common terminology
|
||||
for describing the design.
|
||||
- ~~Detailed design~~ - not implemented yet
|
||||
- [Detailed design](details.md) - In depth description of how generic type
|
||||
parameters work.
|
||||
- ~~Rejected alternatives~~ - not implemented yet
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -58,6 +58,7 @@ request:
|
||||
- [0524 - Generics overview](p0524.md)
|
||||
- [0538 - `return` with no argument](p0538.md)
|
||||
- [0540 - Remove `Void`](p0540.md)
|
||||
- [0553 - Generics details part 1](p0553.md)
|
||||
- [0555 - Operator precedence](p0555.md)
|
||||
- [0561 - Basic classes: use cases, struct literals, struct types, and future work](p0561.md)
|
||||
- [0601 - Operator tokens](p0601.md)
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
# Generics details part 1
|
||||
|
||||
<!--
|
||||
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
Exceptions. See /LICENSE for license information.
|
||||
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
-->
|
||||
|
||||
[Pull request](https://github.com/carbon-language/carbon-lang/pull/553)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Problem](#problem)
|
||||
- [Background](#background)
|
||||
- [Proposal](#proposal)
|
||||
- [Rationale based on Carbon's goals](#rationale-based-on-carbons-goals)
|
||||
- [Alternatives considered](#alternatives-considered)
|
||||
- [Interface implementation syntax](#interface-implementation-syntax)
|
||||
- [`for` instead of `as` in external `impl`](#for-instead-of-as-in-external-impl)
|
||||
- [No `as` for inline `impl`](#no-as-for-inline-impl)
|
||||
- [No `external` for external `impl`](#no-external-for-external-impl)
|
||||
- [Out-of-line impl](#out-of-line-impl)
|
||||
- [`extend` blocks](#extend-blocks)
|
||||
- [Others](#others)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Problem
|
||||
|
||||
We want to Carbon to have a high quality generics feature that achieves the
|
||||
goals set out in [#24](https://github.com/carbon-language/carbon-lang/pull/24).
|
||||
This is too big to land in a single proposal. This proposal goes into the
|
||||
details of the core of the feature, and provides an outline covering future
|
||||
work. It covers:
|
||||
|
||||
- interfaces
|
||||
- implementing interfaces for types
|
||||
- resolving name conflicts
|
||||
- facet types
|
||||
- type-types as the way of describing type variables
|
||||
- structural interfaces
|
||||
- combining interfaces
|
||||
- interface requirements and extension
|
||||
- type compatibility
|
||||
|
||||
## Background
|
||||
|
||||
This is a follow on to these previous generics proposals:
|
||||
|
||||
- [Generics goals #24](https://github.com/carbon-language/carbon-lang/pull/24)
|
||||
- [Generics terminology #447](https://github.com/carbon-language/carbon-lang/pull/447)
|
||||
- [Generics overview #524](https://github.com/carbon-language/carbon-lang/pull/524)
|
||||
|
||||
The content for this proposal was extracted from a larger
|
||||
[Generics combined draft proposal](https://github.com/carbon-language/carbon-lang/pull/36).
|
||||
|
||||
## Proposal
|
||||
|
||||
This is a proposal to add
|
||||
[this detailed design document](/docs/design/generics/details.md).
|
||||
|
||||
## Rationale based on Carbon's goals
|
||||
|
||||
Much of this rationale was captured in the
|
||||
[Generics goals proposal](https://github.com/carbon-language/carbon-lang/pull/24).
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
### Interface implementation syntax
|
||||
|
||||
The interface implementation syntax was decided in
|
||||
[question-for-leads issue #575](https://github.com/carbon-language/carbon-lang/issues/575).
|
||||
|
||||
```
|
||||
struct Song {
|
||||
// data and methods ...
|
||||
impl as Printable {
|
||||
method (me: Self) Print() { ... }
|
||||
}
|
||||
}
|
||||
external impl Song as Comparable { ... }
|
||||
```
|
||||
|
||||
This proposal includes additional discussion and additional alternatives.
|
||||
|
||||
#### `for` instead of `as` in external `impl`
|
||||
|
||||
In this option, the interface name comes before the type name.
|
||||
|
||||
```
|
||||
struct Song { ... }
|
||||
external impl Comparable for Song { ... }
|
||||
```
|
||||
|
||||
Advantage:
|
||||
|
||||
- This ordering used by Rust.
|
||||
|
||||
Disadvantages:
|
||||
|
||||
- We prefer the type name before the interface name (using `as`), since having
|
||||
the type first and outer is consistent with those implemented in `struct`
|
||||
declarations. It also seems more natural to express the parameters to the
|
||||
interface in terms of the parameters and associated items of the type than
|
||||
the other way around.
|
||||
- The `Song as Comparable` phrase is the name of the facet type that is being
|
||||
implemented.
|
||||
|
||||
#### No `as` for inline `impl`
|
||||
|
||||
```
|
||||
struct Song {
|
||||
// data and methods ...
|
||||
impl Printable {
|
||||
method (me: Self) Print() { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Advantage:
|
||||
|
||||
- More concise, so less to read and write.
|
||||
|
||||
Disadvantage:
|
||||
|
||||
- Less consistent with the `external impl` syntax.
|
||||
- Less consistent with the planned inline conditional impl syntax.
|
||||
|
||||
#### No `external` for external `impl`
|
||||
|
||||
```
|
||||
struct Song { ... }
|
||||
impl Song as Comparable { ... }
|
||||
```
|
||||
|
||||
Advantage:
|
||||
|
||||
- More concise, so less to read and write.
|
||||
|
||||
Disadvantages:
|
||||
|
||||
- Less explicit that the the methods of this impl definition are not
|
||||
contributing to unqualified API of the type.
|
||||
- This kind of implementation is naturally referred to as "external",
|
||||
especially when contrasting with "inline impl".
|
||||
|
||||
#### Out-of-line impl
|
||||
|
||||
We considered an out-of-line syntax for declaring and defining interface `impl`
|
||||
blocks, to be consistent with the `external impl` declarations. For example:
|
||||
|
||||
```
|
||||
struct Song { ... }
|
||||
impl Printable for Song { ... }
|
||||
external impl Comparable for Song { ... }
|
||||
```
|
||||
|
||||
The main advantage of this syntax was that it was uniform across many cases,
|
||||
including [conditional conformance](details.md#conditional-conformance). It
|
||||
wasn't ideal across a number of dimensions though.
|
||||
|
||||
- It repeated the type name which was redundant and verbose
|
||||
- It could affect the API of the type outside of the type definition.
|
||||
|
||||
#### `extend` blocks
|
||||
|
||||
Instead of the `external impl` statement, we considered putting all external
|
||||
implementations in an `expand` block.
|
||||
|
||||
```
|
||||
struct Song {
|
||||
impl Printable { ... }
|
||||
}
|
||||
expand Song {
|
||||
impl Comparable { ... }
|
||||
}
|
||||
```
|
||||
|
||||
Advantages:
|
||||
|
||||
- This option is most similar to the
|
||||
[approach used by Swift](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID277).
|
||||
- Easier to copy-paste an `impl` between a `struct` definition and an `expand`
|
||||
block.
|
||||
|
||||
The `expand` approach had some disadvantages:
|
||||
|
||||
- Implementations were indented more than the `external impl` approach.
|
||||
- Extra ceremony in the case of only implementing one type for an interface.
|
||||
This case is expected to be common since external implementations will most
|
||||
often be defined with the interface.
|
||||
- When implementing multiple interfaces in a single `expand` block, the name
|
||||
of the type being expanded could be far from the `impl` declaration and hard
|
||||
to find.
|
||||
|
||||
We originally used `extend` instead of `expand` but that collided with using
|
||||
`extends` for interface extension and derived classes.
|
||||
|
||||
### Others
|
||||
|
||||
Other alternatives considered will be in a future proposal. Some of them can be
|
||||
seen in a rough form in
|
||||
[#36](https://github.com/carbon-language/carbon-lang/pull/36).
|
||||
Reference in New Issue
Block a user