소스 검색

Unused Pattern Bindings (Unused Function Parameters) (#2022)

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

Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Matthew Russo 3 년 전
부모
커밋
b464a0ac3d
1개의 변경된 파일316개의 추가작업 그리고 0개의 파일을 삭제
  1. 316 0
      proposals/p2022.md

+ 316 - 0
proposals/p2022.md

@@ -0,0 +1,316 @@
+# Unused Pattern Bindings (Unused Function Parameters)
+
+<!--
+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/2022
+
+<!-- toc -->
+
+## 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)
+    -   [Attributes](#attributes)
+
+<!-- tocstop -->
+
+## 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 a parameter that is specified
+as unused, but later used, or a parameter that is unused despite not being
+specified as unused.
+
+## 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
+
+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.
+
+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 `_` 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
+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:
+
+-   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
+
+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`
+
+### 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:
+
+-   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
+
+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.