فهرست منبع

Reduce ambiguity in terminology (#3162)

Change terminology away from terms that are ambiguous:

- Reserve "generic type" for types with (compile-time) parameters, like
`Vector` in `Vector(T:! type)`. Don't use that term to refer to `T`, as
it would with
[#2360](https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p2360.md#terminology).
- Use the term "compile-time" instead of "constant" to mean "template or
symbolic." Expand the term "constant" to include values, such as from
`let` bindings.
josh11b 2 سال پیش
والد
کامیت
9600030a05
4فایلهای تغییر یافته به همراه205 افزوده شده و 42 حذف شده
  1. 23 18
      docs/design/README.md
  2. 1 1
      docs/design/expressions/member_access.md
  3. 24 23
      docs/design/generics/terminology.md
  4. 157 0
      proposals/p3162.md

+ 23 - 18
docs/design/README.md

@@ -29,7 +29,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
         -   [String literals](#string-literals)
         -   [String literals](#string-literals)
 -   [Values, objects, and expressions](#values-objects-and-expressions)
 -   [Values, objects, and expressions](#values-objects-and-expressions)
     -   [Expression categories](#expression-categories)
     -   [Expression categories](#expression-categories)
-    -   [Value phases](#value-phases)
+    -   [Expression phases](#expression-phases)
 -   [Composite types](#composite-types)
 -   [Composite types](#composite-types)
     -   [Tuples](#tuples)
     -   [Tuples](#tuples)
     -   [Struct types](#struct-types)
     -   [Struct types](#struct-types)
@@ -399,7 +399,7 @@ Some values, such as `()` and `{}`, may even be used as types, but only act like
 types when they are in a type position, like after a `:` in a variable
 types when they are in a type position, like after a `:` in a variable
 declaration or the return type after a `->` in a function declaration. Any
 declaration or the return type after a `->` in a function declaration. Any
 expression in a type position must be
 expression in a type position must be
-[a constant or symbolic value](#value-phases) so the compiler can resolve
+[a compile-time constant](#expression-phases) so the compiler can resolve
 whether the value can be used as a type. This also puts limits on how much
 whether the value can be used as a type. This also puts limits on how much
 operators can do different things for types. This is good for consistency, but
 operators can do different things for types. This is good for consistency, but
 is a significant restriction on Carbon's design.
 is a significant restriction on Carbon's design.
@@ -688,18 +688,18 @@ The primitive conversion steps used are:
 > -   Proposal
 > -   Proposal
 >     [#2006: Values, variables, pointers, and references](https://github.com/carbon-language/carbon-lang/pull/2006)
 >     [#2006: Values, variables, pointers, and references](https://github.com/carbon-language/carbon-lang/pull/2006)
 
 
-### Value phases
+### Expression phases
 
 
-Value expressions are also broken down into three _value phases_:
+Value expressions are further broken down into three _expression phases_:
 
 
--   A _constant_ has a value known at compile time, and that value is available
-    during type checking, for example to use as the size of an array. These
-    include literals ([integer](#integer-literals),
+-   A _template constant_ has a value known at compile time, and that value is
+    available during type checking, for example to use as the size of an array.
+    These include literals ([integer](#integer-literals),
     [floating-point](#floating-point-literals), [string](#string-literals)),
     [floating-point](#floating-point-literals), [string](#string-literals)),
     concrete type values (like `f64` or `Optional(i32*)`), expressions in terms
     concrete type values (like `f64` or `Optional(i32*)`), expressions in terms
     of constants, and values of
     of constants, and values of
     [`template` parameters](#checked-and-template-parameters).
     [`template` parameters](#checked-and-template-parameters).
--   A _symbolic value_ has a value that will be known at the code generation
+-   A _symbolic constant_ has a value that will be known at the code generation
     stage of compilation when
     stage of compilation when
     [monomorphization](https://en.wikipedia.org/wiki/Monomorphization) happens,
     [monomorphization](https://en.wikipedia.org/wiki/Monomorphization) happens,
     but is not known during type checking. This includes
     but is not known during type checking. This includes
@@ -707,19 +707,23 @@ Value expressions are also broken down into three _value phases_:
     expressions with checked-generic arguments, like `Optional(T*)`.
     expressions with checked-generic arguments, like `Optional(T*)`.
 -   A _runtime value_ has a dynamic value only known at runtime.
 -   A _runtime value_ has a dynamic value only known at runtime.
 
 
-Carbon will automatically convert a constant to a symbolic value, or any value
-to a runtime value:
+Template constants together with symbolic constants are referred to as
+_compile-time constants_.
+
+Carbon will automatically convert a template constant to a symbolic constant, or
+any value to a runtime value:
 
 
 ```mermaid
 ```mermaid
 graph TD;
 graph TD;
-    A(constant)-->B(symbolic value)-->C(runtime value);
+    A(template constant)-->B(symbolic constant)-->C(runtime value);
     D(reference expression)-->C;
     D(reference expression)-->C;
 ```
 ```
 
 
-Constants convert to symbolic values and to runtime values. Symbolic values will
-generally convert into runtime values if an operation that inspects the value is
-performed on them. Runtime values will convert into constants or to symbolic
-values if constant evaluation of the runtime expression succeeds.
+Template constants convert to symbolic constants and to runtime values. Symbolic
+constants will generally convert into runtime values if an operation that
+inspects the value is performed on them. Runtime values will convert into
+template or symbolic constants if constant evaluation of the runtime expression
+succeeds.
 
 
 > **Note:** Conversion of runtime values to other phases is provisional.
 > **Note:** Conversion of runtime values to other phases is provisional.
 
 
@@ -1006,7 +1010,7 @@ the program's correctness must not depend on which option the Carbon
 implementation chooses.
 implementation chooses.
 
 
 A [generic binding](#checked-and-template-parameters) uses `:!` instead of a
 A [generic binding](#checked-and-template-parameters) uses `:!` instead of a
-colon (`:`) and can only match [constant or symbolic values](#value-phases), not
+colon (`:`) and can only match [compile-time constant](#expression-phases), not
 run-time values.
 run-time values.
 
 
 The keyword `auto` may be used in place of the type in a binding pattern, as
 The keyword `auto` may be used in place of the type in a binding pattern, as
@@ -2723,8 +2727,9 @@ templates. Constraints can then be added incrementally, with the compiler
 verifying that the semantics stay the same. Once all constraints have been
 verifying that the semantics stay the same. Once all constraints have been
 added, removing the word `template` to switch to a checked parameter is safe.
 added, removing the word `template` to switch to a checked parameter is safe.
 
 
-The [value phase](#value-phases) of a checked parameter is a symbolic value
-whereas the value phase of a template parameter is constant.
+The [expression phase](#expression-phases) of a checked parameter is a symbolic
+constant whereas the expression phase of a template parameter is template
+constant.
 
 
 Although checked generics are generally preferred, templates enable translation
 Although checked generics are generally preferred, templates enable translation
 of code between C++ and Carbon, and address some cases where the type checking
 of code between C++ and Carbon, and address some cases where the type checking

+ 1 - 1
docs/design/expressions/member_access.md

@@ -583,7 +583,7 @@ fn CallStaticMethod(c: C) {
 
 
   // ✅ OK
   // ✅ OK
   let T:! type = C.Nested;
   let T:! type = C.Nested;
-  // ❌ Error: value of `:!` binding is not constant because it
+  // ❌ Error: value of `:!` binding is not compile-time because it
   // refers to local variable `c`.
   // refers to local variable `c`.
   let U:! type = c.Nested;
   let U:! type = c.Nested;
 }
 }

+ 24 - 23
docs/design/generics/terminology.md

@@ -63,8 +63,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 
 Generally speaking, when we talk about _generics_, either
 Generally speaking, when we talk about _generics_, either
 [checked or template](#checked-versus-template-parameters), we are talking about
 [checked or template](#checked-versus-template-parameters), we are talking about
-generalizing some language construct by adding a compile-time parameter, called
-a _generic parameter_, to it. So:
+generalizing some language construct by adding a _compile-time parameter_, also
+called a _generic parameter_, to it. So:
 
 
 -   a _generic function_ is a function with at least one compile-time parameter,
 -   a _generic function_ is a function with at least one compile-time parameter,
     which could be an explicit argument to the function or
     which could be an explicit argument to the function or
@@ -285,28 +285,28 @@ complete definition checking. This occurs for
 
 
 _Binding patterns_ associate a name with a type and a value. This is used to
 _Binding patterns_ associate a name with a type and a value. This is used to
 declare function parameters, in `let` and `var` declarations, as well as to
 declare function parameters, in `let` and `var` declarations, as well as to
-declare [generic parameters](#generic-means-compile-time-parameterized). There
-are three kinds of binding patterns, corresponding to
-[the three value phases](/docs/design/README.md#value-phases):
+declare [compile-time parameters](#generic-means-compile-time-parameterized) for
+classes, interfaces, and so on. There are three kinds of binding patterns,
+corresponding to
+[the three expression phases](/docs/design/README.md#expression-phases):
 
 
 -   A _runtime binding pattern_ binds to a dynamic value at runtime, and is
 -   A _runtime binding pattern_ binds to a dynamic value at runtime, and is
     written using a `:`, as in `x: i32`.
     written using a `:`, as in `x: i32`.
--   A _symbolic constant binding pattern_ or _symbolic binding pattern_ binds to
-    a compile-time value that is not known when type checking, and is used to
-    declare [checked generic](#checked-versus-template-parameters) parameters.
-    These binding use `:!`, as in `T:! type`.
--   A _template constant binding pattern_ or _template binding pattern_ binds to
-    a compile-time value that is known when type checking, and is used to
-    declare [template](#checked-versus-template-parameters) parameters. These
-    bindings use the keyword `template` in addition to `:!`, as in
-    `template T:! type`.
+-   A _symbolic binding pattern_ binds to a compile-time value that is not known
+    when type checking, and is used to declare
+    [checked generic](#checked-versus-template-parameters) parameters. These
+    binding use `:!`, as in `T:! type`.
+-   A _template binding pattern_ binds to a compile-time value that is known
+    when type checking, and is used to declare
+    [template](#checked-versus-template-parameters) parameters. These bindings
+    use the keyword `template` in addition to `:!`, as in `template T:! type`.
 
 
 The last two binding patterns, which are about binding a compile-time value, are
 The last two binding patterns, which are about binding a compile-time value, are
-called _constant binding patterns_, and correspond to those binding patterns
+called _compile-time binding patterns_, and correspond to those binding patterns
 that use `:!`.
 that use `:!`.
 
 
 The name being declared, which is the identifier to the left of the `:` or `:!`,
 The name being declared, which is the identifier to the left of the `:` or `:!`,
-is called a _binding_, or more specifically a _runtime binding_, _constant
+is called a _binding_, or more specifically a _runtime binding_, _compile-time
 binding_, _symbolic binding_, or _template binding_. The expression to the right
 binding_, _symbolic binding_, or _template binding_. The expression to the right
 defining the type of the binding pattern is called the _binding type
 defining the type of the binding pattern is called the _binding type
 expression_, a kind of [type expression](#type-expression). For example, in
 expression_, a kind of [type expression](#type-expression). For example, in
@@ -368,10 +368,10 @@ cases, we are concerned with the type value after the implicit conversion.
 ## Facet binding
 ## Facet binding
 
 
 We use the term _facet binding_ to refer to the name introduced by a
 We use the term _facet binding_ to refer to the name introduced by a
-[constant binding pattern](#bindings) (using `:!` with or without the `template`
-modifier) where the declared type is a [facet type](#facet-type). In the binding
-pattern `T:! Hashable`, `T` is a facet binding, and the value of `T` is a
-[facet](#facet).
+[compile-time binding pattern](#bindings) (using `:!` with or without the
+`template` modifier) where the declared type is a [facet type](#facet-type). In
+the binding pattern `T:! Hashable`, `T` is a facet binding, and the value of `T`
+is a [facet](#facet).
 
 
 ## Deduced parameter
 ## Deduced parameter
 
 
@@ -848,9 +848,10 @@ that specifies an array bound might have an integer type.
 
 
 ## Type constraints
 ## Type constraints
 
 
-Type constraints restrict which types are legal for generic parameters or
-associated facets. They help define semantics under which they should be called,
-and prevent incorrect calls.
+Type constraints restrict which types are legal for a
+[facet binding](#facet-binding), like a facet parameter or associated facet.
+They help define semantics under which they should be called, and prevent
+incorrect calls.
 
 
 In general there are a number of different type relationships we would like to
 In general there are a number of different type relationships we would like to
 express, for example:
 express, for example:

+ 157 - 0
proposals/p3162.md

@@ -0,0 +1,157 @@
+# Reduce ambiguity in terminology
+
+<!--
+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/3162)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Abstract](#abstract)
+-   [Problem](#problem)
+-   [Background](#background)
+-   [Proposal](#proposal)
+-   [Details](#details)
+-   [Rationale](#rationale)
+-   [Alternatives considered](#alternatives-considered)
+
+<!-- tocstop -->
+
+## Abstract
+
+Change terminology away from terms that are ambiguous:
+
+-   Reserve "generic type" for types with (compile-time) parameters, like
+    `Vector` in `Vector(T:! type)`. Don't use that term to refer to `T`, as it
+    would with [#2360](/proposals/p2360.md#terminology).
+-   Use the term "compile-time" instead of "constant" to mean "template or
+    symbolic." Expand the term "constant" to include values, such as from `let`
+    bindings.
+
+## Problem
+
+Right now, the term "generic type" has two meanings. In this example:
+
+```
+class Vector(T:! type);
+```
+
+Both `Vector` and `T` could be called a "generic type." It would be much less
+confusing if one of those two would have a different name.
+
+Similarly, "constant" can currently mean multiple things:
+
+-   "evaluation at compile time," as in "constant evaluation"
+-   "not variable," as in `let` instead of `var`
+-   "non-mutating view," as in `const T*`
+
+In practice, this has resulted in confusion. For example, the term "constant
+bindings" doesn't include all `let` bindings, even though they are not variable
+bindings.
+
+## Background
+
+The two meanings of "generic type" come from:
+
+-   Proposal [#2360](/proposals/p2360.md#terminology) defines a generic type to
+    be a type or facet introduced by a `:!` binding, such as in a generic
+    parameter or associated constant.
+-   Other uses of the term generic, such as in generic function, mean a language
+    construct with a compile-time parameter (as in
+    [Rust](https://doc.rust-lang.org/rust-by-example/generics.html)). This is
+    the usage in the broader programming language community, and includes
+    calling parameterized types "generic types" (as in
+    [Java](https://docs.oracle.com/javase/tutorial/java/generics/types.html),
+    [.NET](https://learn.microsoft.com/en-us/dotnet/standard/generics/#terminology),
+    [Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/generics/#Generic-Types)).
+
+Issue
+[#1391: New name for "constant" value phase](https://github.com/carbon-language/carbon-lang/issues/1391)
+implemented in proposal
+[#2964: Expression phase terminology](https://github.com/carbon-language/carbon-lang/pull/2964),
+expanded the term "constant" from referring to just template constants to also
+include symbolic constants from checked generics. Since then proposal
+[#2006: Values, variables, pointers, and references](https://github.com/carbon-language/carbon-lang/pull/2006)
+introduced the `const` modifier on types, providing a read-only view.
+
+## Proposal
+
+We make these changes:
+
+-   Reserve "generic type" for types with (compile-time) parameters, like
+    `Vector` in `Vector(T:! type)`. Don't use that term to refer to `T`, as it
+    would with
+    [#2360](https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p2360.md#terminology).
+-   Expand "constant binding" to include all `let` bindings.
+-   Use the term "compile-time binding" to refer to the collection of template
+    and symbolic bindings, such as from generic parameters and associated
+    constants.
+-   Similarly "compile-time constants" to refer to template and symbolic
+    constants, as opposed to just "constants."
+-   The term "compile-time parameter" may be used instead of "generic
+    parameter." For now, both terms will be used, but in the future it might be
+    clearer to only use "generic" to mean "has compile-time parameters."
+-   Only use "symbolic binding" and "template binding" not "symbolic constant
+    binding" nor "template constant binding."
+-   Where applicable, switch from talking about parameters to bindings, since
+    almost everything that applies to compile-time parameters also applies to
+    compile-time bindings. For example, see
+    ["binding patterns"](/docs/design/generics/terminology.md#bindings) and
+    ["facet binding"](/docs/design/generics/terminology.md#facet-binding) in the
+    generics terminology doc.
+
+## Details
+
+The following design documents have been updated in this proposal to reflect
+these changes:
+
+-   [Language design overview](/docs/design/README.md)
+-   [Generics terminology](/docs/design/generics/terminology.md)
+-   [Member access expressions](/docs/design/expressions/member_access.md)
+    **FIXME:** Need to sync with
+    [#3162](https://github.com/carbon-language/carbon-lang/pull/3162).
+
+Some of these changes have already been implemented in:
+
+-   [PR #3048: Update Generics terminology document](https://github.com/carbon-language/carbon-lang/pull/3048)
+-   [PR #3061: Update generics overview](https://github.com/carbon-language/carbon-lang/pull/3061)
+
+## Rationale
+
+This proposal advances these goals of Carbon:
+
+-   [Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem):
+    Having clear and unambiguous terminology is important for making a precise
+    language specification and as well as other design and developer
+    documentation.
+-   [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write):
+    particularly the sub-goal that "The behavior and semantics of code should be
+    clearly and simply specified whenever possible."
+
+## Alternatives considered
+
+The main alternative considered was the status quo. This was discussed:
+
+-   [starting 2023-Jul-14 in #naming](https://discord.com/channels/655572317891461132/963846118964350976/1129542605538074777)
+-   [2023-Jul-27 in open discussion](https://docs.google.com/document/d/1gnJBTfY81fZYvI_QXjwKk1uQHYBNHGqRLI2BS_cYYNQ/edit?resourcekey=0-ql1Q1WvTcDvhycf8LbA9DQ#heading=h.3tki3lncihf)
+-   [2023-Aug-28 in #naming](https://discord.com/channels/655572317891461132/963846118964350976/1145790947083423777)
+
+During those discussions, we also considered "symbolic type" instead of "generic
+type". This did not work out, though, since it conflicted with the term
+"symbolic" used as an expression phase. We considered other possibilities:
+"figurative type", "computed type", "hole type", "open type", and "placeholder
+type" (though that might be better applied to `auto`).
+
+It also came up that we did not want to use the term "generic binding" to mean a
+compile-time binding, because that term would be better applied to a
+parameterized binding, see
+[#naming on 2023-Jul-31](https://discord.com/channels/655572317891461132/963846118964350976/1135704682128494712).
+Those are not currently supported in Carbon, but are something we are likely to
+add. For example,
+[Rust has generic associated types](https://rust-lang.github.io/generic-associated-types-initiative/explainer/motivation.html)
+as of [v1.65](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html).