Selaa lähdekoodia

Disambiguate "value binding" (#6231)

This proposal removes the definition of the term "value binding" as a
primitive
category conversion from reference to value, replacing it with the term
"value
acquisition". The other meaning of "value binding", a binding declared
by a
value binding pattern, is unchanged.
Geoff Romer 6 kuukautta sitten
vanhempi
sitoutus
39503a5561

+ 1 - 1
docs/design/README.md

@@ -702,7 +702,7 @@ similar to [C++](https://en.cppreference.com/w/cpp/language/value_category):
 Expressions in one category can be converted to any other category when needed.
 Expressions in one category can be converted to any other category when needed.
 The primitive conversion steps used are:
 The primitive conversion steps used are:
 
 
--   _Value binding_ converts a reference expression into a value expression.
+-   _Value acquisition_ converts a reference expression into a value expression.
 -   _Direct initialization_ converts a value expression into an initializing
 -   _Direct initialization_ converts a value expression into an initializing
     expression.
     expression.
 -   _Copy initialization_ converts a reference expression into an initializing
 -   _Copy initialization_ converts a reference expression into an initializing

+ 23 - 22
docs/design/values.md

@@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 
 -   [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 binding](#value-binding)
+        -   [Value acquisition](#value-acquisition)
         -   [Direct initialization](#direct-initialization)
         -   [Direct initialization](#direct-initialization)
         -   [Copy initialization](#copy-initialization)
         -   [Copy initialization](#copy-initialization)
         -   [Temporary materialization](#temporary-materialization)
         -   [Temporary materialization](#temporary-materialization)
@@ -80,8 +80,8 @@ There are three expression categories in Carbon:
 Expressions in one category can be converted to any other category when needed.
 Expressions in one category can be converted to any other category when needed.
 The primitive conversion steps used are:
 The primitive conversion steps used are:
 
 
--   [_Value binding_](#value-binding) forms a value expression from the current
-    value of the object referenced by a reference expression.
+-   [_Value acquisition_](#value-acquisition) forms a value expression from the
+    current value of the object referenced by a reference expression.
 -   [_Direct initialization_](#direct-initialization) converts a value
 -   [_Direct initialization_](#direct-initialization) converts a value
     expression into an initializing expression.
     expression into an initializing expression.
 -   [_Copy initialization_](#copy-initialization) converts a reference
 -   [_Copy initialization_](#copy-initialization) converts a reference
@@ -91,11 +91,11 @@ The primitive conversion steps used are:
 
 
 These conversion steps combine to provide the transitive conversion table:
 These conversion steps combine to provide the transitive conversion table:
 
 
-|               From: | value                     | reference | initializing       |
-| ------------------: | ------------------------- | --------- | ------------------ |
-|        to **value** | ==                        | bind      | materialize + bind |
-|    to **reference** | direct init + materialize | ==        | materialize        |
-| to **initializing** | direct init               | copy init | ==                 |
+|               From: | value                     | reference | initializing          |
+| ------------------: | ------------------------- | --------- | --------------------- |
+|        to **value** | ==                        | acquire   | materialize + acquire |
+|    to **reference** | direct init + materialize | ==        | materialize           |
+| to **initializing** | direct init               | copy init | ==                    |
 
 
 Reference expressions formed through temporary materialization are called
 Reference expressions formed through temporary materialization are called
 [_ephemeral reference expressions_](#ephemeral-reference-expressions) and have
 [_ephemeral reference expressions_](#ephemeral-reference-expressions) and have
@@ -105,13 +105,14 @@ to declared storage are called
 restrictions on what is valid, there is no distinction in their behavior or
 restrictions on what is valid, there is no distinction in their behavior or
 semantics.
 semantics.
 
 
-#### Value binding
+#### Value acquisition
 
 
-We call forming a value expression from a reference expression _value binding_.
-This forms a value expression that will evaluate to the value of the object in
-the referenced storage of the reference expression. It may do this by eagerly
-reading that value into a machine register, lazily reading that value on-demand
-into a machine register, or in some other way modeling that abstract value.
+We call forming a value expression from a reference expression _value
+acquisition_. This forms a value expression that will evaluate to the value of
+the object in the referenced storage of the reference expression. It may do this
+by eagerly reading that value into a machine register, lazily reading that value
+on-demand into a machine register, or in some other way modeling that abstract
+value.
 
 
 See the [value expressions](#value-expressions) section for more details on the
 See the [value expressions](#value-expressions) section for more details on the
 semantics of value expressions.
 semantics of value expressions.
@@ -132,8 +133,8 @@ trivially and where this is implemented as a `memcpy` of their underlying bytes.
 #### Temporary materialization
 #### Temporary materialization
 
 
 We use temporary materialization when we need to initialize an object by way of
 We use temporary materialization when we need to initialize an object by way of
-storage, but weren't provided dedicate storage and can simply bind the result to
-a value afterward.
+storage, but weren't provided dedicated storage and can simply acquire the
+result as a value afterward.
 
 
 > **Open question:** The lifetimes of temporaries is not yet specified.
 > **Open question:** The lifetimes of temporaries is not yet specified.
 
 
@@ -235,7 +236,7 @@ occur, which will typically be marked by an open brace (`{`) and close brace
 
 
 ### Consuming function parameters
 ### Consuming function parameters
 
 
-Just as part of a `let` binding can use a `var` prefix to become a variable
+Just as part of a `let` declaration can use a `var` prefix to become a variable
 pattern and bind names that will form reference expressions to the variable's
 pattern and bind names that will form reference expressions to the variable's
 storage, so can function parameters:
 storage, so can function parameters:
 
 
@@ -338,11 +339,11 @@ enable generic code that needs a single type model that will have consistently
 good performance.
 good performance.
 
 
 When forming a value expression from a reference expression, Carbon
 When forming a value expression from a reference expression, Carbon
-[binds](#value-binding) the referenced object to that value expression. This
-allows immediately reading from the object's storage into a machine register or
-a copy if desired, but does not require that. The read of the underlying object
-can also be deferred until the value expression itself is used. Once an object
-is bound to a value expression in this way, any mutation to the object or its
+[acquires](#value-acquisition) the value of the referenced object. This allows
+immediately reading from the object's storage into a machine register or a copy
+if desired, but does not require that. The read of the underlying object can
+also be deferred until the value expression itself is used. Once an object is
+bound to a value expression in this way, any mutation to the object or its
 storage ends the lifetime of the value binding, and makes any use of the value
 storage ends the lifetime of the value binding, and makes any use of the value
 expression an error.
 expression an error.
 
 

+ 85 - 0
proposals/p6231.md

@@ -0,0 +1,85 @@
+# Disambiguate "value binding"
+
+<!--
+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/6231)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Abstract](#abstract)
+-   [Problem](#problem)
+-   [Proposal](#proposal)
+-   [Details](#details)
+-   [Rationale](#rationale)
+-   [Alternatives considered](#alternatives-considered)
+    -   [Rename "a binding declared by a value binding pattern"](#rename-a-binding-declared-by-a-value-binding-pattern)
+    -   [Other names for "primitive conversion from reference to value"](#other-names-for-primitive-conversion-from-reference-to-value)
+
+<!-- tocstop -->
+
+## Abstract
+
+This proposal removes the definition of the term "value binding" as a primitive
+category conversion from reference to value, replacing it with the term "value
+acquisition". The other meaning of "value binding", a binding declared by a
+value binding pattern, is unchanged.
+
+## Problem
+
+The design docs currently define "value binding" in two conflicting ways: it can
+mean the binding declared by a value binding pattern, or it can mean a primitive
+category conversion from reference to value. The two can usually be
+disambiguated based on context, but it's not always straightforward, and the
+double meaning complicates naming within the toolchain implementation.
+
+## Proposal
+
+This proposal removes the definition of the term "value binding" as a primitive
+category conversion from reference to value, replacing it with the term "value
+acquisition".
+
+## Details
+
+See the changes elsewhere in the
+[proposal PR](https://github.com/carbon-language/carbon-lang/pull/6231).
+
+## Rationale
+
+Using unambiguous terminology advances our
+[community and culture](/docs/project/goals.md#community-and-culture) goals, by
+facilitating clear communication.
+
+## Alternatives considered
+
+### Rename "a binding declared by a value binding pattern"
+
+We could instead rename the other meaning of "value binding", but that would be
+considerably more difficult because that meaning appears to be more common, and
+because it's part of a cluster of other heavily-used terms, such as "reference
+binding" and "binding pattern", which we would need to rename for consistency.
+
+### Other names for "primitive conversion from reference to value"
+
+We considered several alternative names before settling on "value acquisition":
+
+-   "Value borrowing" highlights the close analogy to Rust borrowing, which
+    similarly forbids mutation of the object for the lifetime of the borrow.
+    However, this naming choice somewhat prejudges the safety story for this
+    operation.
+-   "Value snapshotting" and "value observation" may not effectively communicate
+    the ongoing coupling between the object and the value.
+-   "Value capturing" reuses and extends the existing meaning of "capturing" in
+    lambdas. However, it may be confusing that a lambda can have value captures
+    that are not initialized by value capturing (for example because the
+    initializer is a value, not a reference).
+-   "Value expression conversion" is straightforward and hard to misunderstand.
+    However, we sometimes use "value binding" to refer to the _result_ of a
+    reference-to-value conversion, for example "the lifetime of a value
+    binding". "Value expression conversion" doesn't seem to lend itself to that
+    usage, possibly because it's too generic to be a recognizable term of art.

+ 1 - 1
toolchain/check/member_access.cpp

@@ -420,7 +420,7 @@ static auto PerformInstanceBinding(Context& context, SemIR::LocId loc_id,
             SemIR::ExprCategory::Value) {
             SemIR::ExprCategory::Value) {
       // Class element access on a value expression produces an ephemeral
       // Class element access on a value expression produces an ephemeral
       // reference if the class's value representation is a pointer to the
       // reference if the class's value representation is a pointer to the
-      // object representation. Add a value binding in that case so that the
+      // object representation. Add a value acquisition in that case so that the
       // expression category of the result matches the expression category
       // expression category of the result matches the expression category
       // of the base.
       // of the base.
       access_id = ConvertToValueExpr(context, access_id);
       access_id = ConvertToValueExpr(context, access_id);

+ 2 - 2
toolchain/lower/handle_expr_category.cpp

@@ -14,10 +14,10 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
   switch (context.GetValueRepr(inst_type).repr.kind) {
   switch (context.GetValueRepr(inst_type).repr.kind) {
     case SemIR::ValueRepr::Unknown:
     case SemIR::ValueRepr::Unknown:
       CARBON_FATAL(
       CARBON_FATAL(
-          "Value binding for type with incomplete value representation");
+          "Value acquisition for type with incomplete value representation");
     case SemIR::ValueRepr::Dependent:
     case SemIR::ValueRepr::Dependent:
       CARBON_FATAL(
       CARBON_FATAL(
-          "Value binding for type with dependent value representation");
+          "Value acquisition for type with dependent value representation");
     case SemIR::ValueRepr::None:
     case SemIR::ValueRepr::None:
       // Nothing should use this value, but StubRef needs a value to
       // Nothing should use this value, but StubRef needs a value to
       // propagate.
       // propagate.

+ 2 - 2
toolchain/lower/testdata/class/value_access.carbon

@@ -15,9 +15,9 @@ class C {
 }
 }
 
 
 fn F(c: C) -> i32 {
 fn F(c: C) -> i32 {
-  // TODO: `c.a` is a value expression here, which forces a value binding as
+  // TODO: `c.a` is a value expression here, which forces a value acquisition as
   // part of the member access, creating a tuple value temporary. We could
   // part of the member access, creating a tuple value temporary. We could
-  // defer performing the value binding to avoid creating this temporary.
+  // defer performing the value acquisition to avoid creating this temporary.
   return c.a.1;
   return c.a.1;
 }
 }
 
 

+ 3 - 2
toolchain/sem_ir/typed_insts.h

@@ -287,8 +287,9 @@ struct BindSymbolicName {
   InstId value_id;
   InstId value_id;
 };
 };
 
 
-// A value binding. Used when an expression contains a reference and we want a
-// value.
+// A value acquisition. Used when an expression contains a reference and we want
+// a value.
+// TODO: Rename to AcquireValue
 struct BindValue {
 struct BindValue {
   static constexpr auto Kind =
   static constexpr auto Kind =
       InstKind::BindValue.Define<Parse::NodeId>({.ir_name = "bind_value"});
       InstKind::BindValue.Define<Parse::NodeId>({.ir_name = "bind_value"});