From 60f91b180f7df0852e26a8dcbacbe490a0004ffe Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 21 Mar 2022 19:45:43 +0000 Subject: [PATCH 01/13] Filling out template with PR 1146 --- proposals/p1146.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 proposals/p1146.md diff --git a/proposals/p1146.md b/proposals/p1146.md new file mode 100644 index 0000000000000..29a49a5b73e7d --- /dev/null +++ b/proposals/p1146.md @@ -0,0 +1,62 @@ +# Generics 12: Parameterized types + + + +[Pull request](https://github.com/carbon-language/carbon-lang/pull/1146) + + + +## Table of contents + +- [Problem](#problem) +- [Background](#background) +- [Proposal](#proposal) +- [Details](#details) +- [Rationale based on Carbon's goals](#rationale-based-on-carbons-goals) +- [Alternatives considered](#alternatives-considered) + + + +## Problem + +TODO: What problem are you trying to solve? How important is that problem? Who +is impacted by it? + +## Background + +TODO: Is there any background that readers should consider to fully understand +this problem and your approach to solving it? + +## Proposal + +TODO: Briefly and at a high level, how do you propose to solve the problem? Why +will that in fact solve it? + +## Details + +TODO: Fully explain the details of the proposed solution. + +## Rationale based on Carbon's goals + +TODO: How does this proposal effectively advance Carbon's goals? Rather than +re-stating the full motivation, this should connect that motivation back to +Carbon's stated goals for the project or language. This may evolve during +review. Use links to appropriate goals, for example: + +- [Community and culture](/docs/project/goals.md#community-and-culture) +- [Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem) +- [Performance-critical software](/docs/project/goals.md#performance-critical-software) +- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution) +- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) +- [Practical safety and testing mechanisms](/docs/project/goals.md#practical-safety-and-testing-mechanisms) +- [Fast and scalable development](/docs/project/goals.md#fast-and-scalable-development) +- [Modern OS platforms, hardware architectures, and environments](/docs/project/goals.md#modern-os-platforms-hardware-architectures-and-environments) +- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code) + +## Alternatives considered + +TODO: What alternative solutions have you considered? From 8866a86293d65e2a0a11f616d7767ac2aaae9afb Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 21 Mar 2022 22:02:45 +0000 Subject: [PATCH 02/13] Specialization --- docs/design/generics/details.md | 102 ++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 6 deletions(-) diff --git a/docs/design/generics/details.md b/docs/design/generics/details.md index 1543ecccd61dd..2a822c9387acf 100644 --- a/docs/design/generics/details.md +++ b/docs/design/generics/details.md @@ -95,6 +95,9 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Interface members with definitions](#interface-members-with-definitions) - [Interface defaults](#interface-defaults) - [`final` members](#final-members) +- [Generic types](#generic-types) + - [Type identity](#type-identity) + - [Specialization](#specialization) - [Future work](#future-work) - [Dynamic types](#dynamic-types) - [Runtime type parameters](#runtime-type-parameters) @@ -108,7 +111,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Generic associated types](#generic-associated-types) - [Higher-ranked types](#higher-ranked-types) - [Field requirements](#field-requirements) - - [Generic type specialization](#generic-type-specialization) - [Bridge for C++ customization points](#bridge-for-c-customization-points) - [Variadic arguments](#variadic-arguments) - [Range constraints on generic integers](#range-constraints-on-generic-integers) @@ -4440,6 +4442,98 @@ There are a few reasons for this feature: Note that this applies to associated entities, not interface parameters. +## Generic types + +FIXME: A _generic_ type is a class with generic parameters. + +FIXME: All type parameters must be either generic or template, never dynamic. + +### Type identity + +FIXME: Two types are the same if they have the same name and same 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 +[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. +Types, like functions, may not be specialized directly in Carbon. This effect +can be achieved, however, through delegation. + +For example, imagine we have a parameterized class `Optional(T)` that has a +default storage strategy that works for all `T`, but for some types we have a +more efficient approach. For pointers we can use a +[null value](https://en.wikipedia.org/wiki/Null_pointer) to represent "no +pointer", and for booleans we can support `True`, `False`, and `None` in a +single byte. Clients of the optional library may want to add additional +specializations for their own types. We make an interface that represents "the +storage of `Optional(T)` for type `T`," written here as `OptionalStorage`: + +``` +interface OptionalStorage { + let Storage:! Type; + fn MakeNone() -> Storage; + fn Make(x: Self) -> Storage; + fn IsNone(x: Storage) -> bool; + fn Unwrap(x: Storage) -> Self; +} +``` + +The default implementation of this interface is provided by a +[blanket implementation](#blanket-impls): + +``` +// Default blanket implementation +impl [T:! Movable] T as OptionalStorage { + let Storage:! Type = (bool, T); + ... +} +``` + +This implementation can then be +[specialized](#lookup-resolution-and-specialization) for more specific type +patterns: + +``` +// Specialization for pointers, using nullptr == None +final external impl [T:! Type] T* as OptionalStorage { + let Storage:! Type = Array(Byte, sizeof(T*)); + ... +} +// Specialization for type `bool`. +final external impl bool as OptionalStorage { + let Storage:! Type = Byte; + ... +} +``` + +Further, libraries can implement `OptionalStorage` for their own types, assuming +the interface is not marked `private`. Then the implementation of `Optional(T)` +can delegate to `OptionalStorage` for anything that can vary with `T`: + +``` +class Optional(T:! Movable) { + fn None() -> Self { + return {.storage = T.(OptionalStorage.MakeNone())}; + } + fn Some(x: T) -> Self { + return {.storage = T.(OptionalStorage.Make(x))}; + } + ... + private var storage: T.(OptionalStorage.Storage); +} +``` + +Note that the constraint on `T` is just `Movable`, not +`Movable & OptionalStorage`, since the `Movable` requirement is +[sufficient to guarantee](#lookup-resolution-and-specialization) that some +implementation of `OptionalStorage` exists for `T`. Adding `OptionalStorage` to +the constraints on `T` would make `Optional` harder for clients and obscure what +types can be used with `Optional`. + ## Future work ### Dynamic types @@ -4521,11 +4615,6 @@ implementing type has a particular field. This would be to match the expressivity of inheritance, which can express "all subtypes start with this list of fields." -### Generic type specialization - -See [generic specialization](terminology.md#generic-specialization) for a -description of what this might involve. - ### Bridge for C++ customization points See details in [the goals document](goals.md#bridge-for-c-customization-points). @@ -4570,3 +4659,4 @@ be included in the declaration as well. - [#983: Generic details 7: final impls](https://github.com/carbon-language/carbon-lang/pull/983) - [#990: Generics details 8: interface default and final members](https://github.com/carbon-language/carbon-lang/pull/990) - [#1013: Generics: Set associated constants using where constraints](https://github.com/carbon-language/carbon-lang/pull/1013) +- [#1146: Generics 12: Parameterized type](https://github.com/carbon-language/carbon-lang/pull/1146) From 240a7256df8149a231b455198c663a2c0cf598e5 Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 21 Mar 2022 22:07:03 +0000 Subject: [PATCH 03/13] Title again --- docs/design/generics/details.md | 2 +- proposals/p1146.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design/generics/details.md b/docs/design/generics/details.md index 2a822c9387acf..1ca5d95865f19 100644 --- a/docs/design/generics/details.md +++ b/docs/design/generics/details.md @@ -4659,4 +4659,4 @@ be included in the declaration as well. - [#983: Generic details 7: final impls](https://github.com/carbon-language/carbon-lang/pull/983) - [#990: Generics details 8: interface default and final members](https://github.com/carbon-language/carbon-lang/pull/990) - [#1013: Generics: Set associated constants using where constraints](https://github.com/carbon-language/carbon-lang/pull/1013) -- [#1146: Generics 12: Parameterized type](https://github.com/carbon-language/carbon-lang/pull/1146) +- [#1146: Generic details 12: Parameterized types](https://github.com/carbon-language/carbon-lang/pull/1146) diff --git a/proposals/p1146.md b/proposals/p1146.md index 29a49a5b73e7d..a4e632d2dd7a6 100644 --- a/proposals/p1146.md +++ b/proposals/p1146.md @@ -1,4 +1,4 @@ -# Generics 12: Parameterized types +# Generic details 12: Parameterized types