Files
carbon-lang/docs/design/templates.md
T
Jon Meow d031f3cdab An incomplete, early, and in-progress overview of the language design. (#83)
Co-authored by: chandlerc

- Based on [PR 22](https://github.com/carbon-language/carbon-lang/pull/83)
- [Idea topic](https://forums.carbon-lang.dev/t/proposal-for-an-incomplete-rough-high-level-overview-ready-for-early-feedback/52)
- [RFC](https://forums.carbon-lang.dev/t/rfc-an-incomplete-early-and-in-progress-overview-of-the-language-design/73)
- [Decision announcement](https://forums.carbon-lang.dev/t/accepted-an-incomplete-early-and-in-progress-overview-of-the-language-design/110)

This proposal should be considered a starting point of the language design. It's not intended to be final; language details may change. This is intended to offer a reasonable starting point for:

- Example code.
- Conceptualizing Carbon at a high level.
- Reasonable, but not necessarily final, approaches to features in README.md.
  - If any idea is obviously bad, we can clean it up here.

This proposal is not intended to achieve:

- A whole language design.
  - This is way too much work for a single proposal; this is a skeletal framework only.
  - As we work on feature-specific designs, we may decide to use other approaches. That's fine: we only need somewhere to start.
  - The summaries in README.md may be expected to change over time.
- Feature-specific files aren't intended to be well-written or comprehensive. They are a quick jot of prior thoughts.
  - We want to avoid getting stuck on language details that we should consider
    more carefully regardless. If you're passionate about a feature, please feel
    free to start a new proposal for it.
  - Each and every aspect of the suggested overview should be subject to careful
    examination and justification before it becomes a settled plan of record.

Chandler started this with https://github.com/carbon-language/carbon-lang/pull/22. I've taken it over with the following changes:

- More of a directory hierarchy.
- Trying to thin out the main file (now README.md) to lighter summaries of features.
- Details/rationale/alternatives should be in feature-specific files.
  - Draft files are linked as references where added.

For an example of how we may proceed with feature-specific designs, see https://github.com/carbon-language/carbon-lang/pull/80. In this structure:

- docs/design/README.md mentions interoperability, with a light overview.
  - The light overview is not yet in https://github.com/carbon-language/carbon-lang/pull/80.
- docs/design/interoperability/README.md goes into more depth on interoperability, covering key points of the approach.
- Individual files in docs/design/interoperability/* go into more depth on interoperability.

Simple designs may not have a subdirectory. All current feature-specific designs do not -- they may be moved later.
2020-07-30 11:37:15 -07:00

4.4 KiB

Templates

Table of contents

TODO

This is a skeletal design, added to support the overview. It should not be treated as accepted by the core team; rather, it is a placeholder until we have more time to examine this detail. Please feel welcome to rewrite and update as appropriate.

Overview

Carbon templates follow the same fundamental paradigm as C++ templates: they are instantiated, resulting in late type checking, duck typing, and lazy binding. They both enable interoperability between Carbon and C++ and address some (hopefully limited) use cases where the type checking rigor imposed by generics isn't helpful.

Types with template parameters

When parameterizing a user-defined type, the parameters can be marked as template parameters. The resulting type-function will instantiate the parameterized definition with the provided arguments to produce a complete type when used. Note that only the parameters marked as having this template behavior are subject to full instantiation -- other parameters will be type checked and bound early to the extent possible. For example:

struct Stack(Type:$$ T) {
  var Array(T): storage;

  fn Push(T: value);
  fn Pop() -> T;
}

This both defines a parameterized type (Stack) and uses one (Array). Within the definition of the type, the template type parameter T can be used in all of the places a normal type would be used, and it will only by type checked on instantiation.

Functions with template parameters

Both implicit and explicit function parameters in Carbon can be marked as template parameters. When called, the arguments to these parameters trigger instantiation of the function definition, fully type checking and resolving that definition after substituting in the provided (or computed if implicit) arguments. The runtime call then passes the remaining arguments to the resulting complete definition.

fn Convert[Type:$$ T](T: source, Type:$$ U) -> U {
  var U: converted = source;
  return converted;
}

fn Foo(Int: i) -> Float {
  // Instantiates with the `T` implicit argument set to `Int` and the `U`
  // explicit argument set to `Float`, then calls with the runtime value `i`.
  return Convert(i, Float);
}

Here we deduce one type parameter and explicitly pass another. It is not possible to explicitly pass a deduced type parameter, instead the call site should cast or convert the argument to control the deduction. The explicit type is passed after a runtime parameter. While this makes that type unavailable to the declaration of that runtime parameter, it still is a template parameter and available to use as a type even within the remaining parts of the function declaration.

Overloading

An important feature of templates in C++ is the ability to customize how they end up specialized for specific types. Because template parameters (whether as type parameters or function parameters) are pattern matched, we expect to leverage pattern matching techniques to provide "better match" definitions that are selected analogously to specializations in C++ templates. When expressed through pattern matching, this may enable things beyond just template parameter specialization, but that is an area that we want to explore cautiously.

Constraining templates with interfaces

Because we consider only specific parameters to be templated and they could be individually migrated to a constrained interface using the generics system, constraining templates themselves may be less critical. Instead, we expect parameterized types and functions may use a mixture of generic parameters and templated parameters based on where they are constrained.

However, if there are still use cases, we would like to explore applying the interface constraints of the generics system directly to template parameters rather than create a new constraint system.