We want to Carbon to have a high quality generics feature that achieves the goals set out in #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:
This is a follow on to these previous generics proposals:
The content for this proposal was extracted from a larger Generics combined draft proposal.
This is a proposal to add this detailed design document.
Much of this rationale was captured in the Generics goals proposal.
The interface implementation syntax was decided in question-for-leads issue #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 implIn this option, the interface name comes before the type name.
struct Song { ... }
external impl Comparable for Song { ... }
Advantage:
Disadvantages:
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.Song as Comparable phrase is the name of the facet type that is being
implemented.as for inline implstruct Song {
// data and methods ...
impl Printable {
method (me: Self) Print() { ... }
}
}
Advantage:
Disadvantage:
external impl syntax.external for external implstruct Song { ... }
impl Song as Comparable { ... }
Advantage:
Disadvantages:
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. It wasn't ideal across a number of dimensions though.
extend blocksInstead of the external impl statement, we considered putting all external
implementations in an expand block.
struct Song {
impl Printable { ... }
}
expand Song {
impl Comparable { ... }
}
Advantages:
impl between a struct definition and an expand
block.The expand approach had some disadvantages:
external impl approach.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.
Other alternatives considered will be in a future proposal. Some of them can be seen in a rough form in #36.