Names and entities in a program can come from multiple sources -- from a local declaration, from an import, from the standard library, or from the prelude. Names can be imported from Carbon code or imported or derived from code written in another language such as C++ or an interface description language such as that of Protobuf, MIDL, or CORBA. Names can be selected for use in a program that language designers later decide they want to use as keywords. And in order to use a library, it is sometimes necessary to redeclare the same name that that library chose.
This puts a lot of pressure on the language to support a free choice of naming for entities. Different languages make different choices in this space:
klass or class_), which sometimes conflicts with the general
naming convention used by the code. And conversely, suboptimal choices are
made for new language keywords to avoid causing problems for existing code.__identifier(keyword) extension that allows using a
keyword as an identifier. This extension is also implemented by Clang in
-fms-extensions mode.__asm__(symbol) extension that allows a specific
symbol to be assigned to an object or function, which provides ABI
compatibility but not source compatibility with code that uses a keyword
as a symbol name. This extension is also implemented by Clang.bool) and reserves some identifiers but rejects
assignment to them (such as True).self, Self, super, extern, and crate cannot be used as raw
identifiers. Rust also predeclares a large number of library names in every
file, but allows them to be shadowed by user declarations with the same
name.`class`, and
is
considering
extending this to allow arbitrary non-word-shaped character sequences
between the `s.Carbon provides
raw identifier syntax,
for example r#for, to allow using keywords as identifiers. Carbon also intends
to have strict shadowing rules that may make predeclared identifiers that are
not keywords difficult or impossible to redeclare and use in inner scopes.
In Carbon, the language does not encroach on the developer's namespace. There
are no predeclared or reserved identifiers. In cases where the language gives
special meaning to a word or to word-shaped syntax such as i32, that special
meaning can always be undone with raw identifier syntax, r#.
Conversely, when adding language keywords, we will not select an inferior
keyword merely to avoid the risk of breaking existing programs. We will still
take into account how often it is desirable to use the word as an identifier,
including in domain-specific contexts, because that is a factor in whether it
would make a good keyword, and will manage the rollout of new keywords to make
it straightforward to migrate existing uses to r# or a different name.
final and base that only have special meaning in a few
contexts, and could otherwise be made available as identifiers, are keywords
in Carbon. {.base = ...} and {.r#base = ...} specify different member
names.self that are declared by the developer but nonetheless have
special language-recognized meaning are keywords in Carbon. [self:! Self]
introduces a self parameter; [r#self:! Self] introduces a deduced
parameter.Self that are implicitly declared by the language in some
contexts are keywords, even though we could treat them as user-declared
identifiers that are merely implicitly declared in some cases.i32 that are treated as type literals rather than keywords can
be used as identifiers with raw identifier syntax r#i32.r#.Core is a keyword. A package named r#Core
is an unrelated package, and Core.foo always refers to members of the
predeclared Core package.For now, we reserve the package names Main and Cpp. These names aren't
predeclared in any scope, and the name Main is not even usable from within
source files to refer to the main package. However, there is currently no way to
avoid collisions between the package name Cpp and a top-level entity named
Cpp if they are both used in the same source file.