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

Update Generics terminology document #3048

Merged
merged 8 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions docs/design/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,7 @@ class MyDerivedClass {

The properties of a type, whether type is abstract, base, or final, and whether
the destructor is virtual or non-virtual, determines which
[type-of-types](/docs/design/generics/terminology.md#type-of-type) it satisfies.
[type-of-types](/docs/design/generics/terminology.md#facet-type) it satisfies.

- Non-abstract classes are `Concrete`. This means you can create local and
member variables of this type. `Concrete` types have destructors that are
Expand Down Expand Up @@ -1623,7 +1623,7 @@ conform to the decision on
| final | any | yes | yes | yes |

The compiler automatically determines which of these
[type-of-types](/docs/design/generics/terminology.md#type-of-type) a given type
[type-of-types](/docs/design/generics/terminology.md#facet-type) a given type
satisfies. It is illegal to directly implement `Concrete`, `Deletable`, or
`Destructible` directly. For more about these constraints, see
["destructor constraints" in the detailed generics design](/docs/design/generics/details.md#destructor-constraints).
Expand Down
4 changes: 2 additions & 2 deletions docs/design/expressions/implicit_conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ var r: Base** = &p;

### Type-of-types

A type `T` with [type-of-type](../generics/terminology.md#type-of-type) `TT1`
can be implicitly converted to the type-of-type `TT2` if `T`
A type `T` with [type-of-type](../generics/terminology.md#facet-type) `TT1` can
be implicitly converted to the type-of-type `TT2` if `T`
[satisfies the requirements](../generics/details.md#subtyping-between-type-of-types)
of `TT2`.

Expand Down
63 changes: 32 additions & 31 deletions docs/design/generics/details.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ When the implementation of `ConvertibleToString` for `Song` is defined as
internal, every member of `ConvertibleToString` is also a member of `Song`. This
includes members of `ConvertibleToString` that are not explicitly named in the
`impl` definition but have defaults. Whether the implementation is defined as
[internal](terminology.md#internal-impl) or
[external](terminology.md#external-impl), you may access the `ToString` function
for a `Song` value `s` by a writing function call
[internal](terminology.md#extending-an-impl) or
[external](terminology.md#extending-an-impl), you may access the `ToString`
function for a `Song` value `s` by a writing function call
[using a qualified member access expression](terminology.md#qualified-member-access-expression),
like `s.(ConvertibleToString.ToString)()`.

Expand Down Expand Up @@ -359,8 +359,8 @@ class Player {
### External impl

Interfaces may also be implemented for a type
[externally](terminology.md#external-impl), by using `impl` without `extend`. An
external impl does not add the interface's methods to the type.
[externally](terminology.md#extending-an-impl), by using `impl` without
`extend`. An external impl does not add the interface's methods to the type.

```
class Point2 {
Expand Down Expand Up @@ -597,7 +597,7 @@ var v: Point = AddAndScaleGeneric(a, w, 2.5);
```

Here `T` is a type whose type is `Vector`. The `:!` syntax means that `T` is a
_[generic parameter](terminology.md#generic-versus-template-parameters)_. That
_[generic parameter](terminology.md#checked-versus-template-parameters)_. That
means it must be known to the caller, but we will only use the information
present in the signature of the function to type check the body of
`AddAndScaleGeneric`'s definition. In this case, we know that any value of type
Expand Down Expand Up @@ -628,13 +628,13 @@ acts like a [supertype](https://en.wikipedia.org/wiki/Subtyping) of any `T`
implementing `Vector`.

For name lookup purposes, an archetype is considered to have
[implemented its constraint internally](terminology.md#internal-impl). The only
oddity is that the archetype may have different names for members than specific
types `T` that implement interfaces from the constraint
[externally](terminology.md#external-impl). This difference in names can also
occur for supertypes in C++, for example members in a derived class can hide
members in the base class with the same name, though it is not that common for
it to come up in practice.
[implemented its constraint internally](terminology.md#extending-an-impl). The
only oddity is that the archetype may have different names for members than
specific types `T` that implement interfaces from the constraint
[externally](terminology.md#extending-an-impl). This difference in names can
also occur for supertypes in C++, for example members in a derived class can
hide members in the base class with the same name, though it is not that common
for it to come up in practice.

The behavior of calling `AddAndScaleGeneric` with a value of a specific type
like `Point` is to set `T` to `Point` after all the names have been qualified.
Expand All @@ -648,8 +648,8 @@ fn AddAndScaleForPoint(a: Point, b: Point, s: Double) -> Point {

This qualification gives a consistent interpretation to the body of the function
even when the type supplied by the caller
[implements the interface externally](terminology.md#external-impl), as `Point2`
does:
[implements the interface externally](terminology.md#extending-an-impl), as
`Point2` does:

```
// AddAndScaleGeneric with T = Point2
Expand Down Expand Up @@ -805,15 +805,15 @@ An interface's name may be used in a few different contexts:
- to define [an `impl` for a type](#implementing-interfaces),
- as a namespace name in
[a qualified name](#qualified-member-names-and-compound-member-access), and
- as a [type-of-type](terminology.md#type-of-type) for
- as a [type-of-type](terminology.md#facet-type) for
[a generic type parameter](#generics).

While interfaces are examples of type-of-types, type-of-types are a more general
concept, for which interfaces are a building block.

## Type-of-types

A [type-of-type](terminology.md#type-of-type) consists of a set of requirements
A [type-of-type](terminology.md#facet-type) consists of a set of requirements
and a set of names. Requirements are typically a set of interfaces that a type
must satisfy, though other kinds of requirements are added below. The names are
aliases for qualified names in those interfaces.
Expand Down Expand Up @@ -883,7 +883,7 @@ whenever an interface may be. This includes all of these
[a qualified name](#qualified-member-names-and-compound-member-access). For
example, `VectorLegoFish.VAdd` refers to the same name as `Vector.Add`.
- A named constraint may be used as a
[type-of-type](terminology.md#type-of-type) for
[type-of-type](terminology.md#facet-type) for
[a generic type parameter](#generics).

We don't expect developers to directly define many named constraints, but other
Expand Down Expand Up @@ -1910,7 +1910,7 @@ fn Complex64.CloserToOrigin[self: Self](them: Self) -> bool {
### Use case: Accessing external names

Consider a case where a function will call several functions from an interface
that is [implemented externally](terminology.md#external-impl) for a type.
that is [implemented externally](terminology.md#extending-an-impl) for a type.

```
interface DrawingContext {
Expand All @@ -1924,9 +1924,10 @@ impl Window as DrawingContext { ... }
```

An adapter can make that much more convenient by making a compatible type where
the interface is [implemented internally](terminology.md#internal-impl). This
avoids having to [qualify](terminology.md#qualified-member-access-expression)
each call to methods in the interface.
the interface is [implemented internally](terminology.md#extending-an-impl).
This avoids having to
[qualify](terminology.md#qualified-member-access-expression) each call to
methods in the interface.

```
class DrawInWindow {
Expand Down Expand Up @@ -2195,7 +2196,7 @@ class DynamicArray(T:! type) {
```

For context, see
["Interface type parameters and associated types" in the generics terminology document](terminology.md#interface-type-parameters-and-associated-types).
["Interface type parameters and associated types" in the generics terminology document](terminology.md#interface-parameters-and-associated-constants).

**Comparison with other languages:** Both
[Rust](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types)
Expand Down Expand Up @@ -2245,7 +2246,7 @@ interface at most once.
If instead you want a family of related interfaces, one per possible value of a
type parameter, multiple of which could be implemented for a single type, you
would use
[parameterized interfaces](terminology.md#interface-type-parameters-and-associated-types).
[parameterized interfaces](terminology.md#interface-parameters-and-associated-constants).
To write a parameterized version of the stack interface, instead of using
associated types, write a parameter list after the name of the interface instead
of the associated type declaration:
Expand Down Expand Up @@ -3166,8 +3167,8 @@ fn F[T:! Transitive](t: T) {
A value of type `A`, such as the return value of `GetA()`, has the API of `P`.
Any such value also implements `Q`, and since the compiler can see that by way
of a single `where` equality, values of type `A` are treated as if they
implement `Q` [externally](terminology.md#external-impl). However, the compiler
will require a cast to `B` or `C` to see that the type implements `R`.
implement `Q` [externally](terminology.md#extending-an-impl). However, the
compiler will require a cast to `B` or `C` to see that the type implements `R`.

```
fn TakesPQR[U:! P & Q & R](u: U);
Expand Down Expand Up @@ -3624,8 +3625,8 @@ In particular, the compiler should in general avoid monomorphizing to generate
multiple instantiations of the function in this case.

**Open question:** Should `TypeId` be
[implemented externally](terminology.md#external-impl) for types to avoid name
pollution (`.TypeName`, `.TypeHash`, etc.) unless the function specifically
[implemented externally](terminology.md#extending-an-impl) for types to avoid
name pollution (`.TypeName`, `.TypeHash`, etc.) unless the function specifically
requests those capabilities?

### Destructor constraints
Expand Down Expand Up @@ -5695,9 +5696,9 @@ be [implied constraints](#implied-constraints) on the function's parameters.

### Specialization

[Specialization](terminology.md#generic-specialization) is used to improve
performance in specific cases when a general strategy would be inefficient. For
example, you might use
[Specialization](terminology.md#checked-generic-specialization) is used to
improve performance in specific cases when a general strategy would be
inefficient. For example, you might use
[binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) for
containers that support random access and keep their contents in sorted order
but [linear search](https://en.wikipedia.org/wiki/Linear_search) in other cases.
Expand Down
18 changes: 9 additions & 9 deletions docs/design/generics/goals.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,18 @@ forward-looking.

## Background

Carbon will support
[generics](terminology.md#generic-versus-template-parameters) to support generic
programming by way of
[parameterization of language constructs](terminology.md#parameterized-language-constructs)
with [early type checking](terminology.md#early-versus-late-type-checking) and
Carbon will support both
[checked and template generics](terminology.md#checked-versus-template-parameters)
to support generic programming by way of
[compile-time parameterization of language constructs](terminology.md#generic-means-compile-time-parameterized).

Carbon's checked generics will feature
[early type checking](terminology.md#early-versus-late-type-checking) and
[complete definition checking](terminology.md#complete-definition-checking).

This is in contrast with the
Carbon's template generics, in contrast, will more closely follow the
[compile-time duck typing](https://en.wikipedia.org/wiki/Duck_typing#Templates_or_generic_types)
approach of C++ templates, and _in addition_ to
[template support in Carbon](#relationship-to-templates), if we decide to
support templates in Carbon beyond interoperability with C++ templates.
approach of C++ templates.

### Generic parameters

Expand Down
6 changes: 3 additions & 3 deletions docs/design/generics/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ definition is required after seeing the call sites once all the
[instantiations](terminology.md#instantiation) are known.

Note: [Generics terminology](terminology.md) goes into more detail about the
[differences between generics and templates](terminology.md#generic-versus-template-parameters).
[differences between generics and templates](terminology.md#checked-versus-template-parameters).

### Implementing interfaces

Expand Down Expand Up @@ -259,7 +259,7 @@ specific type value assigned to `T` is not known when type checking the
`SortVector` function. Instead it is the constraints on `T` that let the
compiler know what operations may be performed on values of type `T`. Those
constraints are represented by the type of `T`, a
[**_type-of-type_**](terminology.md#type-of-type).
[**_type-of-type_**](terminology.md#facet-type).

In general, a type-of-type describes the capabilities of a type, while a type
defines specific implementations of those capabilities. An interface, like
Expand Down Expand Up @@ -519,7 +519,7 @@ specific sort order.

### Interface input and output types

[Associated types and interface parameters](terminology.md#interface-type-parameters-and-associated-types)
[Associated types and interface parameters](terminology.md#interface-parameters-and-associated-constants)
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
Expand Down
Loading