The goal of this proposal is to establish naming conventions for:
fn or for.i32.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.
Naming conventions are an issue frequently addressed by style guides. A few examples of language-provided guidelines are:
Related issues:
Related proposals:
Only UpperCamelCase and lower_snake_case conventions will be used, in order
to minimize the variation in rules.
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.lower_snake_case.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 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. |
Supposing let might be used to designate a constant, consider the following
code:
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 items are split into a few categories:
for, fn, and vari<digits>, u<digits>, and f<digits>bool, true, and false
Self and BaseInt, UInt, and StringNote 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.
UpperCamelCase and lower_snake_case
will offer developers a limited number of style rules to learn.for as well as booleans.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.In detail, individual naming decisions that had alternative patterns or options discussed were:
lower_snake_case as described in issue
#543: pick names for fixed-size integer types.
i8 is more ergonomic than Int8 for brevity.i32 and i64 maintain the same length as C++'s int.I32 because I32 can be hard to visually
distinguish with 132 or l32, even though it may help screen readers.bool, true, and false mainly because there's a desire not
to skew from C++.
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.
String and potentially other names follow idiomatic naming conventions.
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:
import is always
lower_snake_case.
i32, bool, true, self, base, string.is_empty()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.