From 479c79f668a803a1d9c63cbf2c158c20bed13e1c Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Fri, 12 Aug 2022 21:22:36 -0700 Subject: [PATCH 01/10] Creating new proposal: Optional Argument Names (Unused Arguments) --- proposals/p2022.md | 280 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 proposals/p2022.md diff --git a/proposals/p2022.md b/proposals/p2022.md new file mode 100644 index 0000000000000..5d76d29f63da0 --- /dev/null +++ b/proposals/p2022.md @@ -0,0 +1,280 @@ +# Unused Pattern Bindings (Unused Function Parameters) + + + +[Pull request](https://github.com/carbon-language/carbon-lang/pull/2022 + + + +## Table of contents + +- [Abstract](#abstract) +- [Problem](#problem) +- [Background](#background) +- [Proposal](#proposal) +- [Details](#details) + - [The behavior of `unused` name bindings](#the-behavior-of-unused-name-bindings) + - [Examples](#examples) +- [Rationale](#rationale) +- [Alternatives considered](#alternatives-considered) + - [Commented names](#commented-names) + - [Only short form support with `_`](#only-short-form-support-with-_) + - [Named identifiers prefixed with `_`](#named-identifiers-prefixed-with-_) + - [Anonymous, named identifiers](#anonymous-named-identifiers) + + + +## Abstract + +This proposal specifies how unused pattern bindings are written in the Carbon +programming language. This is a more general problem statement of "how do users +specify unused function parameters" as function parameter declarations are a +more specific form of pattern. + +Related issue: +[#1996](https://github.com/carbon-language/carbon-lang/issues/1996). + +## Problem + +"How does a user of Carbon declare an unused pattern binding?" + +Given that function parameters are a specific type of pattern binding, a more +specific question that will have the same answer is "How does a user of Carbon +declare an unused function parameter?" + +Bindings that can be specified as unused makes code explicit and unambiguous. +Authors of code can clearly state that a value is not intended to be used. Tools +such as compilers or linters can explicitly handle an argument that is specified +as unused, but later used. + +## Background + +See +[the overall design](https://github.com/carbon-language/carbon-lang/blob/09e4417431b77c05ceb2a98dd38833276514a1ff/docs/design/README.md#binding-patterns) +for the current state of things with regards to name bindings and the underscore +character, `_`. + +See +[issue #476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) +for the previous conversation on this topic. + +Note: These are not exhaustive lists and not intended to be thoroughly +investigated, rather a brief overview of some prior art. + +C and C++ style guides, linters, and other tools have addressed unused function +parameters specifically with varying levels of clarity for readers. + +- [Standard C++ Foundation's guidelines on unused parameters](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-unused) +- [Google's C++ style guide recommendations on unused parameters](https://google.github.io/styleguide/cppguide.html#Function_Declarations_and_Definitions) +- [C++ `maybe_unused` attribute](https://en.cppreference.com/w/cpp/language/attributes/maybe_unused) +- [GCC C `unused` attribute](https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#index-g_t_0040code_007bunused_007d-attribute_002e-2640) + +More generally, various languages use the underscore character (`_`) to signal +an unused binding or pattern. + +- [Rust `_` Patterns](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html#ignoring-values-in-a-pattern) +- [Golang Blank Identifiers](https://go.dev/ref/spec#Blank_identifier) +- [PyLint allows parameters starting with `_`, `ignored_`, or `unused_` to be unused](https://pylint.pycqa.org/en/latest/user_guide/configuration/all-options.html#ignored-argument-names) +- [Scala Wildcard Patterns](https://www.scala-lang.org/files/archive/spec/2.11/10-pattern-matching.html#variable-patterns) +- [Crystal `_` Cases](https://crystal-lang.org/reference/1.5/syntax_and_semantics/case.html#underscore-allowed) + +## Proposal + +Users can explicitly declare a value in a pattern as unused in two forms: + +- `_: i32` : Using the underscore token, `_`, in place of a name. + +- `unused size: i32` : Using the leading `unused` keyword followed by the + name. + +## Details + +i32roducing two syntaxes satisfies the desire to have a terse way to discard +values, but still provides authors with a more verbose, explicit syntax that +preserves the name. + +Both approaches are unambiguous -- to human readers and authors as well as +programmatic interpretations. The inclusion of an explicit `unused` keyword +allows authors to preserve the name of a value for documentation purposes, while +still explicitly marking the value as discarded in an interpretable way to +humans and programs alike. + +The `unused` keyword would be a new keyword in Carbon. This keyword would only +be valid when preceding a name in a pattern binding and the keyword would +tightly bind to the following name, disallowing specifying an entire sub-pattern +as `unused`. + +### The behavior of `unused` name bindings + +Names that are qualified with the `unused` keyword are visible for name lookup +but uses are invalid, including when they cause ambiguous name lookup errors. If +attempted to be used, a compiler error will be shown to the user, instructing +them to either remove the `unused` qualifier or remove the use. + +The inverse, where a name is not qualified by the `unused` qualifier, but never +used, will cause the compiler to emit a warning diagnostic, informing the user +that a given name was not used and suggesting to either remove the binding or +mark it as unused. + +### Examples + +Examples with an unused function parameter + +```carbon +// Function declaration (may be in API file) +fn Sum(x: List(i32), size: i32) -> i32; + +// Implementation that doesn't use the size parameter +fn Sum(x: List(i32), _: i32) -> i32 { ... } +// or: +fn Sum(x: List(i32), unused size: i32) -> i32 { ... } +``` + +Examples with an unused variable + +```carbon +fn Bar() -> (i32, i32); +fn Foo() -> i32 { + var (x: i32, _: i32) = Bar(); + // or: + var (x: i32, unused y: i32) = Bar(); + + return x; +} +``` + +Examples with an unused case binding + +```carbon +fn Bar() -> (i32, i32); +fn Foo() -> i32 { + match (Bar()) { + case (42, y: i32) => { + return y; + } + case (x: i32, _: i32) => { + return x; + } + // or: + case (x: i32, unused y: i32) => { + return x; + } + } +} +``` + +## Rationale + +- This proposal supports the Carbon goal of having + [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) +- Carbon should not use symbols that are difficult to type, see, or + differentiate from similar symbols in commonly used contexts. +- Syntax should be easily parsed and scanned by any human in any development + environment, not just a machine or a human aided by semantic hints from an + IDE. +- Explicitness must be balanced against conciseness, as verbosity and ceremony + add cognitive overhead for the reader, while explicitness reduces the amount + of outside context the reader must have or assume. + +This proposal uses the underscore, `_`, character to denote an unused value, a +meaning used across various other programming languages. A lone underscore +character only has a single meaning in Carbon and will be unambiguous across +contexts. + +Both syntaxes are easily read by humans, either by seeing the `_` chacter alone, +or by introducing a keyword that allows code to read naturally such as +`unused size : i32`. + +The inclusion of two syntaxes allows authors to decide when they will favor +conciseness or explicitness. + +## Alternatives considered + +### Commented names + +C++ allows function parameters to be unnamed, allowing function declarations +such as + +``` +int Foo(int) { ... } +int Foo(int /*unused_name*/) { ... } +``` + +Advantages: + +- Consistency with C++ + +Disadvantages: + +- Carbon does not intend to support `/* */` comments, so this option is + effectively a non-starter + +### Only short form support with `_` + +Carbon could provide only a single way to discard a value with the underscore, +`_`, token + +``` +// Function declaration (may be in API file) +fn Sum(x: List(i32), size: i32) -> i32; + +// Implementation that doesn't use the size parameter +fn Sum(x: List(i32), _: i32) -> i32 { ... } +``` + +Advantages: + +- A smaller language, one less keyword, and a single way to write code + +Disadvantages: + +- Less expressiveness, less documentation through names + +### Named identifiers prefixed with `_` + +Carbon could treat identifiers prefixed with `_` as unused identifiers and +discard their names. + +``` +// Function declaration (may be in API file) +fn Sum(x: List(i32), size: i32) -> i32; + +// Implementation that doesn't use the size parameter +fn Sum(x: List(i32), _size: i32) -> i32 { ... } +``` + +Advantages: + +- Reuse of the underscore character in both short and long form bindings +- Functionally similar to commented names in C++ + +Disadvantages: + +- Interpreting the `_` character within an identifier name rather than using a + standalone token can be viewed as excessively clever + +### Anonymous, named identifiers + +A potential syntax for naming unused bindings while retaining the underscore, +`_`, token is an optional name suffix following the underscore token. + +``` +// Function declaration (may be in API file) +fn Sum(x: List(i32), size: i32) -> i32; + +// Implementation that doesn't use the size parameter +fn Sum(x: List(i32), _ size: i32) -> i32 { ... } +``` + +Advantages: + +- Reuse of the underscore token in both short and long form bindings + +Disadvantages: + +- The underscore token, while consistent, may be less human readable than a + dedicated keyword such as `unused` From 3ac484d872c424966717924a8e5a5d6feb104497 Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Thu, 8 Sep 2022 19:13:28 -0700 Subject: [PATCH 02/10] Update p2022 : fix overzealous search-and-replace --- proposals/p2022.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 5d76d29f63da0..30e7491b1cfe7 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -93,7 +93,7 @@ Users can explicitly declare a value in a pattern as unused in two forms: ## Details -i32roducing two syntaxes satisfies the desire to have a terse way to discard +Intoducing two syntaxes satisfies the desire to have a terse way to discard values, but still provides authors with a more verbose, explicit syntax that preserves the name. From 2bd78effeae5444594c2c22540e6e042301f988c Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Thu, 8 Sep 2022 19:16:37 -0700 Subject: [PATCH 03/10] Update p2022 : make bullets under Rationale section sub-points --- proposals/p2022.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 30e7491b1cfe7..405e838e1425c 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -171,14 +171,14 @@ fn Foo() -> i32 { - This proposal supports the Carbon goal of having [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) -- Carbon should not use symbols that are difficult to type, see, or - differentiate from similar symbols in commonly used contexts. -- Syntax should be easily parsed and scanned by any human in any development - environment, not just a machine or a human aided by semantic hints from an - IDE. -- Explicitness must be balanced against conciseness, as verbosity and ceremony - add cognitive overhead for the reader, while explicitness reduces the amount - of outside context the reader must have or assume. + - Carbon should not use symbols that are difficult to type, see, or + differentiate from similar symbols in commonly used contexts. + - Syntax should be easily parsed and scanned by any human in any + development environment, not just a machine or a human aided by semantic + hints from an IDE. + - Explicitness must be balanced against conciseness, as verbosity and + ceremony add cognitive overhead for the reader, while explicitness + reduces the amount of outside context the reader must have or assume. This proposal uses the underscore, `_`, character to denote an unused value, a meaning used across various other programming languages. A lone underscore From 9fee8ad7ccc5ead1b2b2de6ebbc3d8401632ec53 Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Sun, 11 Sep 2022 11:24:02 -0700 Subject: [PATCH 04/10] Update proposals/p2022.md Co-authored-by: Geoff Romer --- proposals/p2022.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 405e838e1425c..7ea33d1b87916 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -93,7 +93,7 @@ Users can explicitly declare a value in a pattern as unused in two forms: ## Details -Intoducing two syntaxes satisfies the desire to have a terse way to discard +Introducing two syntaxes satisfies the desire to have a terse way to discard values, but still provides authors with a more verbose, explicit syntax that preserves the name. From cdeaca202babb0bee27010c23434304fc174ec9c Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Sun, 11 Sep 2022 11:27:11 -0700 Subject: [PATCH 05/10] Update proposal 2022 : elaborate on why interpreting identifier names for semantic meaning is disadvantageous --- proposals/p2022.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 7ea33d1b87916..159ac1dacc89e 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -254,8 +254,16 @@ Advantages: Disadvantages: -- Interpreting the `_` character within an identifier name rather than using a - standalone token can be viewed as excessively clever +- Tying the semantics of a name being unused to the particular spelling of the + identifier (starting with a `_` character), even while it remains an + identifier seems more subtle and indirect than necessary. + - We shouldn't use identifier spellings as a side-channel for semantic + information. + - Semantics, including used versus unused, should be conveyed in an + orthogonal manner to the name rather than tying them together. +- Would require the name to change when shifting between being used or unused, + which could undermine some of its utility such as remaining for annotations, + metaprogramming, or diagnostics. ### Anonymous, named identifiers From 9b75900e029e74d3a2dfda0a93d9a903ebe52c5f Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Wed, 14 Sep 2022 19:55:49 -0700 Subject: [PATCH 06/10] Update proposals/p2022.md Co-authored-by: Richard Smith --- proposals/p2022.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 159ac1dacc89e..35c73e3369c56 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -48,8 +48,9 @@ declare an unused function parameter?" Bindings that can be specified as unused makes code explicit and unambiguous. Authors of code can clearly state that a value is not intended to be used. Tools -such as compilers or linters can explicitly handle an argument that is specified -as unused, but later used. +such as compilers or linters can explicitly handle a parameter that is specified +as unused, but later used, or a parameter that is unused despite not being +specified as unused. ## Background From 8f3bcb66276ca2513c72527443e6a21489ef5587 Mon Sep 17 00:00:00 2001 From: Matthew Russo Date: Sat, 17 Sep 2022 09:11:55 -0700 Subject: [PATCH 07/10] Update proposal 2022 : add an alternative for attributes --- proposals/p2022.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/proposals/p2022.md b/proposals/p2022.md index 35c73e3369c56..35eb6ff0ae265 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -25,6 +25,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Only short form support with `_`](#only-short-form-support-with-_) - [Named identifiers prefixed with `_`](#named-identifiers-prefixed-with-_) - [Anonymous, named identifiers](#anonymous-named-identifiers) + - [Attributes](#attributes) @@ -287,3 +288,29 @@ Disadvantages: - The underscore token, while consistent, may be less human readable than a dedicated keyword such as `unused` + +### Attributes + +While attributes aren't designed yet, there's a possibility that in the future, +the Carbon language will have some mechanism to attach metadata to parts of +source code to inform readers, compilers, and other tools. Its conceivable that +there could be an `unused` attribute which could be use to implement similar +semantics as the proposed `unused` keyword. + +Advantages: + +- Open the inspection and subsequent actions taken to the whatever ecosystem + and programmatic support introduced by attributes. +- Solves a specific problem with a generic approach + - Removes the introduction of a new keyword + +Disadvantages: + +- Given the current proposal where `unused` bindings specify unambiguous, + absolute behavior for the compiler's handling of names, similar to the + `private` keyword, using attributes as the transport for this semantic + information is indirect. + +Given that attributes are not designed and may go in a number of unknown +directions, it might be worth revisiting this option once attributes are fully +designed. From 56e5e35490ef0f012bf1307f02349311e14dc976 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 20 Sep 2022 17:00:13 -0700 Subject: [PATCH 08/10] Minor grammar change. --- proposals/p2022.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 35eb6ff0ae265..1b4d877c6dd6f 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -299,8 +299,8 @@ semantics as the proposed `unused` keyword. Advantages: -- Open the inspection and subsequent actions taken to the whatever ecosystem - and programmatic support introduced by attributes. +- Opens the inspection and subsequent actions taken to whatever ecosystem + and programmatic support is introduced by attributes. - Solves a specific problem with a generic approach - Removes the introduction of a new keyword From 0e025111a6c320f2e3f76b8d560d43a0bebe04cf Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 20 Sep 2022 17:03:44 -0700 Subject: [PATCH 09/10] Fix wrapping from previous change for pre-commit. --- proposals/p2022.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index 1b4d877c6dd6f..fd461d7913ed3 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -299,8 +299,8 @@ semantics as the proposed `unused` keyword. Advantages: -- Opens the inspection and subsequent actions taken to whatever ecosystem - and programmatic support is introduced by attributes. +- Opens the inspection and subsequent actions taken to whatever ecosystem and + programmatic support is introduced by attributes. - Solves a specific problem with a generic approach - Removes the introduction of a new keyword From bd5707050322a368b372abe6929ae11a48478b89 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 20 Sep 2022 17:07:15 -0700 Subject: [PATCH 10/10] Fix typo. --- proposals/p2022.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/p2022.md b/proposals/p2022.md index fd461d7913ed3..a845b95611833 100644 --- a/proposals/p2022.md +++ b/proposals/p2022.md @@ -187,8 +187,8 @@ meaning used across various other programming languages. A lone underscore character only has a single meaning in Carbon and will be unambiguous across contexts. -Both syntaxes are easily read by humans, either by seeing the `_` chacter alone, -or by introducing a keyword that allows code to read naturally such as +Both syntaxes are easily read by humans, either by seeing the `_` character +alone, or by introducing a keyword that allows code to read naturally such as `unused size : i32`. The inclusion of two syntaxes allows authors to decide when they will favor