|
|
@@ -0,0 +1,216 @@
|
|
|
+# Naming conventions
|
|
|
+
|
|
|
+<!--
|
|
|
+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/861)
|
|
|
+
|
|
|
+<!-- toc -->
|
|
|
+
|
|
|
+## Table of contents
|
|
|
+
|
|
|
+- [Problem](#problem)
|
|
|
+- [Background](#background)
|
|
|
+ - [Cross-language precedent](#cross-language-precedent)
|
|
|
+ - [Carbon artifacts](#carbon-artifacts)
|
|
|
+- [Proposal](#proposal)
|
|
|
+- [Details](#details)
|
|
|
+ - [Constants](#constants)
|
|
|
+ - [Carbon-provided item naming](#carbon-provided-item-naming)
|
|
|
+- [Open questions](#open-questions)
|
|
|
+- [Rationale based on Carbon's goals](#rationale-based-on-carbons-goals)
|
|
|
+- [Alternatives considered](#alternatives-considered)
|
|
|
+ - [Other naming conventions](#other-naming-conventions)
|
|
|
+ - [Other conventions for naming Carbon types](#other-conventions-for-naming-carbon-types)
|
|
|
+
|
|
|
+<!-- tocstop -->
|
|
|
+
|
|
|
+## Problem
|
|
|
+
|
|
|
+The goal of this proposal is to establish naming conventions for:
|
|
|
+
|
|
|
+- Idiomatic Carbon code.
|
|
|
+- Carbon-provided features, including:
|
|
|
+ - Keywords, such as `fn` or `for`.
|
|
|
+ - Type literals, such as `i32`.
|
|
|
+ - Types, such as `bool` or `String`.
|
|
|
+
|
|
|
+The reason for resolving this through proposal is to ensure we're headed in a
|
|
|
+reasonably consistent path as we write early documentation and example code.
|
|
|
+
|
|
|
+## Background
|
|
|
+
|
|
|
+### Cross-language precedent
|
|
|
+
|
|
|
+Naming conventions are an issue frequently addressed by style guides. A few
|
|
|
+examples of language-provided guidelines are:
|
|
|
+
|
|
|
+- [Effective Go](https://golang.org/doc/effective_go#names)
|
|
|
+- [Python's PEP 8](https://www.python.org/dev/peps/pep-0008/#naming-conventions)
|
|
|
+ - Note PEP 8 offers a list of
|
|
|
+ [naming styles](https://www.python.org/dev/peps/pep-0008/#descriptive-naming-styles).
|
|
|
+- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/naming.html)
|
|
|
+- [Swift's API Design Guidelines](https://swift.org/documentation/api-design-guidelines/#general-conventions)
|
|
|
+
|
|
|
+### Carbon artifacts
|
|
|
+
|
|
|
+Related issues:
|
|
|
+
|
|
|
+- Issue
|
|
|
+ [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543)
|
|
|
+ covers numeric type literal naming.
|
|
|
+- Issue
|
|
|
+ [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
|
|
+ was used for initial naming convention discussion.
|
|
|
+
|
|
|
+Related proposals:
|
|
|
+
|
|
|
+- Proposal
|
|
|
+ [#720: Property naming in C++](https://github.com/carbon-language/carbon-lang/pull/720)
|
|
|
+ covers nuances of property naming.
|
|
|
+
|
|
|
+## Proposal
|
|
|
+
|
|
|
+Only `UpperCamelCase` and `lower_snake_case` conventions will be used, in order
|
|
|
+to minimize the variation in rules.
|
|
|
+
|
|
|
+- For idiomatic Carbon code:
|
|
|
+ - `UpperCamelCase` will be used when the named entity cannot have a
|
|
|
+ dynamically varying value. For example, functions, namespaces, or
|
|
|
+ compile-time constant values.
|
|
|
+ - `lower_snake_case` will be used when the named entity's value won't be
|
|
|
+ known until runtime, such as for variables.
|
|
|
+- For Carbon-provided features:
|
|
|
+ - Keywords and type literals will use `lower_snake_case`.
|
|
|
+ - Other code will use the guidelines for idiomatic Carbon code.
|
|
|
+
|
|
|
+In other words:
|
|
|
+
|
|
|
+| Item | Convention | Explanation |
|
|
|
+| ------------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
|
|
|
+| Packages | `UpperCamelCase` | Used for compile-time lookup. |
|
|
|
+| Types | `UpperCamelCase` | Resolved at compile-time. |
|
|
|
+| Functions | `UpperCamelCase` | Resolved at compile-time. |
|
|
|
+| Methods | `UpperCamelCase` | Methods, including virtual methods, are equivalent to functions. |
|
|
|
+| Generic parameters | `UpperCamelCase` | May vary based on inputs, but are ultimately resolved at compile-time. |
|
|
|
+| Compile-time constants | `UpperCamelCase` | Resolved at compile-time. See [constants](#constants) for more remarks. |
|
|
|
+| Variables | `lower_snake_case` | May be reassigned and thus require runtime information. |
|
|
|
+| Member variables | `lower_snake_case` | Behave like variables. |
|
|
|
+| Keywords | `lower_snake_case` | Special, and developers can be expected to be comfortable with this casing cross-language. |
|
|
|
+| Type literals | `lower_snake_case` | Equivalent to keywords. |
|
|
|
+| Boolean type and literals | `lower_snake_case` | Equivalent to keywords. |
|
|
|
+| Other Carbon types | `UpperCamelCase` | Behave like normal types. |
|
|
|
+| `Self` and `Base` | `UpperCamelCase` | These are similar to type members on a class. |
|
|
|
+
|
|
|
+## Details
|
|
|
+
|
|
|
+### Constants
|
|
|
+
|
|
|
+Supposing `let` might be used to designate a constant, consider the following
|
|
|
+code:
|
|
|
+
|
|
|
+```carbon
|
|
|
+package Example;
|
|
|
+
|
|
|
+let CompileTimeConstant: i32 = 7;
|
|
|
+
|
|
|
+fn RuntimeFunction(runtime_constant: i32);
|
|
|
+```
|
|
|
+
|
|
|
+In this example, `CompileTimeConstant` has a singular value (`7`) which is known
|
|
|
+at compile-time. As such, it uses `UpperCamelCase`.
|
|
|
+
|
|
|
+On the other hand, `runtime_constant` may be constant within the function body,
|
|
|
+but it is assigned at runtime when `RuntimeFunction` is called. Its value is
|
|
|
+only known in a given runtime invocation of `RuntimeFunction`. As such, it uses
|
|
|
+`lower_snake_case`.
|
|
|
+
|
|
|
+### Carbon-provided item naming
|
|
|
+
|
|
|
+Carbon-provided items are split into a few categories:
|
|
|
+
|
|
|
+- Keywords; for example, `for`, `fn`, and `var`
|
|
|
+- Type literals; for example, `i<digits>`, `u<digits>`, and `f<digits>`
|
|
|
+- Boolean type and literals; for example, `bool`, `true`, and `false`
|
|
|
+ - The separate categorization of booleans should not be taken as a rule
|
|
|
+ that only booleans would use lowercase; it's just the only example right
|
|
|
+ now.
|
|
|
+- `Self` and `Base`
|
|
|
+- Other Carbon types; for example, `Int`, `UInt`, and `String`
|
|
|
+
|
|
|
+Note that while other Carbon types currently use `UpperCamelCase`, that should
|
|
|
+not be inferred to mean that future Carbon types will do the same. The leads
|
|
|
+will make decisions on future naming.
|
|
|
+
|
|
|
+## Open questions
|
|
|
+
|
|
|
+## Rationale based on Carbon's goals
|
|
|
+
|
|
|
+- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
|
|
|
+ - The intent is that limiting to `UpperCamelCase` and `lower_snake_case`
|
|
|
+ will offer developers a limited number of style rules to learn.
|
|
|
+ - There is a desire to maintain good ergonomics for developers.
|
|
|
+- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code)
|
|
|
+ - There is a general desire to maintain naming consistency with C++, and
|
|
|
+ this can be seen with keywords such as `for` as well as booleans.
|
|
|
+
|
|
|
+## Alternatives considered
|
|
|
+
|
|
|
+### Other naming conventions
|
|
|
+
|
|
|
+A couple naming conventions that were discussed briefly are:
|
|
|
+
|
|
|
+- `lowerCamelCase` names came up, but are hard to distinguish from
|
|
|
+ `lower_snake_case` for single-word identifiers. By contrast,
|
|
|
+ `UpperCamelCase` and `lower_snake_case` are distinct, whether a single word
|
|
|
+ or multiple.
|
|
|
+- `ALL_CAPS_SNAKE_CASE` is used in C++ code, such as for macros and
|
|
|
+ compile-time constants. With Carbon, we hope the language is simple enough
|
|
|
+ that the readability benefit of an additional naming convention wouldn't
|
|
|
+ outweigh the cost of giving developers more naming conventions to learn.
|
|
|
+
|
|
|
+### Other conventions for naming Carbon types
|
|
|
+
|
|
|
+In detail, individual naming decisions that had alternative patterns or options
|
|
|
+discussed were:
|
|
|
+
|
|
|
+- Type literals use `lower_snake_case` as described in issue
|
|
|
+ [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543).
|
|
|
+ - `i8` is more ergonomic than `Int8` for brevity.
|
|
|
+ - `i32` and `i64` maintain the same length as C++'s `int`.
|
|
|
+ - We don't want to use `I32` because `I32` can be hard to visually
|
|
|
+ distinguish with `132` or `l32`, even though it may help screen readers.
|
|
|
+- Booleans use `bool`, `true`, and `false` mainly because there's a desire not
|
|
|
+ to skew from C++.
|
|
|
+ - While leads are okay with some things being shadowed, such as `Self` and
|
|
|
+ `Base`, there is a desire not to allow shadowing of booleans.
|
|
|
+- `Self` and `Base` are `UpperCamelCase` because leads want them to look more
|
|
|
+ like normal types.
|
|
|
+ - They may be implemented as a hybrid approach, using something similar to
|
|
|
+ lookup in classes so they aren't quite keywords, but somewhat similar to
|
|
|
+ keywords because leads may want to reject them as identifiers in
|
|
|
+ non-class contexts.
|
|
|
+- `String` and potentially other names follow idiomatic naming conventions.
|
|
|
+ - Note that, in this case, divergence from C++ is accepted.
|
|
|
+
|
|
|
+Taking that into consideration, and that we are likely to keep
|
|
|
+`lower_snake_case` for keywords and type literals in particular, a couple
|
|
|
+options discussed would have mainly affect `self`, `base`, and `string`:
|
|
|
+
|
|
|
+- Anything language-provided without needing an `import` is always
|
|
|
+ `lower_snake_case`.
|
|
|
+ - `i32`, `bool`, `true`, `self`, `base`, `string.is_empty()`
|
|
|
+- As above, but prelude class members follow standard naming conventions.
|
|
|
+ - `i32`, `bool`, `true`, `self`, `base`, `string.IsEmpty()`
|
|
|
+
|
|
|
+The understanding is that the difference between `bool` being treated similarly
|
|
|
+to a keyword and `Self` being treated similarly to a type (both regardless of
|
|
|
+implementation) is somewhat arbitrary. The decision not to use
|
|
|
+`lower_snake_case` consistently depends mainly on the leaning of the leads, that
|
|
|
+`self` and `base` felt like they shouldn't strictly be treated as keywords, and
|
|
|
+`string` felt like the point where users should expect something more like an
|
|
|
+idiomatic class. Future borderline cases may need to be decided by leads whether
|
|
|
+they should be treated as more keyword-like or type-like.
|