mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 10:31:03 +01:00
- For idiomatic Carbon code:
- `UpperCamelCase` will be used when the identifier can be resolved to a
specific value at compile-time.
- `lower_snake_case` will be used when the identifier'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.
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: josh11b <josh11b@users.noreply.github.com>
217 lines
10 KiB
Markdown
217 lines
10 KiB
Markdown
# 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.
|