|
@@ -0,0 +1,177 @@
|
|
|
|
|
+# No predeclared identifiers, `Core` is a keyword
|
|
|
|
|
+
|
|
|
|
|
+<!--
|
|
|
|
|
+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/4864)
|
|
|
|
|
+
|
|
|
|
|
+<!-- toc -->
|
|
|
|
|
+
|
|
|
|
|
+## Table of contents
|
|
|
|
|
+
|
|
|
|
|
+- [Abstract](#abstract)
|
|
|
|
|
+- [Problem](#problem)
|
|
|
|
|
+- [Background](#background)
|
|
|
|
|
+- [Proposal](#proposal)
|
|
|
|
|
+- [Details](#details)
|
|
|
|
|
+- [Rationale](#rationale)
|
|
|
|
|
+- [Future work](#future-work)
|
|
|
|
|
+ - [Package name `Cpp`](#package-name-cpp)
|
|
|
|
|
+ - [Package name `Main`](#package-name-main)
|
|
|
|
|
+- [Alternatives considered](#alternatives-considered)
|
|
|
|
|
+ - [Have both predeclared identifiers and keywords](#have-both-predeclared-identifiers-and-keywords)
|
|
|
|
|
+ - [Reserve words with a certain spelling](#reserve-words-with-a-certain-spelling)
|
|
|
|
|
+
|
|
|
|
|
+<!-- tocstop -->
|
|
|
|
|
+
|
|
|
|
|
+## Abstract
|
|
|
|
|
+
|
|
|
|
|
+Introduce a principle that the Carbon language should not encroach on the
|
|
|
|
|
+developer's namespace. Satisfy this principle by making `Core` a keyword.
|
|
|
|
|
+
|
|
|
|
|
+## Problem
|
|
|
|
|
+
|
|
|
|
|
+Ongoing design work needs rules for how to expose types such as a primitive
|
|
|
|
|
+array type to Carbon code, and in particular, if we choose to make it available
|
|
|
|
|
+by default, whether that should be accomplished by a keyword or a predeclared
|
|
|
|
|
+identifier.
|
|
|
|
|
+
|
|
|
|
|
+## Background
|
|
|
|
|
+
|
|
|
|
|
+See the
|
|
|
|
|
+[Background section of the added principle](/docs/project/principles/namespace_cleanliness.md#background).
|
|
|
|
|
+
|
|
|
|
|
+## Proposal
|
|
|
|
|
+
|
|
|
|
|
+We choose to not have any predeclared identifiers in Carbon. If a word has
|
|
|
|
|
+special meaning to the language, then that word is a keyword, and a plain
|
|
|
|
|
+identifier with no special meaning is always available using raw identifier
|
|
|
|
|
+syntax.
|
|
|
|
|
+
|
|
|
|
|
+## Details
|
|
|
|
|
+
|
|
|
|
|
+See [the principle document](/docs/project/principles/namespace_cleanliness.md)
|
|
|
|
|
+for details of the added principle. In addition, we make one change and one
|
|
|
|
|
+clarification:
|
|
|
|
|
+
|
|
|
|
|
+- `Core` is changed from being an identifier that happens to be the name of
|
|
|
|
|
+ the Carbon standard library, and happens to be predeclared in every source
|
|
|
|
|
+ file as naming that library, to being a keyword. The keyword can only be
|
|
|
|
|
+ used:
|
|
|
|
|
+
|
|
|
|
|
+ - When importing the `Core` package.
|
|
|
|
|
+ - When implementing the `Core` package as part of the language
|
|
|
|
|
+ implementation.
|
|
|
|
|
+ - As a keyword naming the `Core` package, much like the `package` keyword.
|
|
|
|
|
+
|
|
|
|
|
+ The identifier `r#Core` can be used freely and does not conflict with the
|
|
|
|
|
+ keyword. This includes use of `r#Core` as the name of a package. Language
|
|
|
|
|
+ constructs that are defined in terms of entities in the `Core` package refer
|
|
|
|
|
+ specifically to the package named with the _keyword_ `Core`, not to any
|
|
|
|
|
+ other entity named `Core`.
|
|
|
|
|
+
|
|
|
|
|
+- The `self` keyword is now included in the list of keywords. It is already
|
|
|
|
|
+ treated as a keyword by the toolchain.
|
|
|
|
|
+
|
|
|
|
|
+## Rationale
|
|
|
|
|
+
|
|
|
|
|
+- [Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem)
|
|
|
|
|
+ - Code generation tools can have a uniform handling for all words with
|
|
|
|
|
+ special meaning, with no need to alter the spelling of names from other
|
|
|
|
|
+ languages.
|
|
|
|
|
+ - Language tools can determine the meaning of `Core.<name>` without
|
|
|
|
|
+ needing to do any name lookup or sophisticated analysis.
|
|
|
|
|
+- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution)
|
|
|
|
|
+ - Migration between versions of Carbon with a changed set of reserved
|
|
|
|
|
+ words can be done uniformly.
|
|
|
|
|
+ - Adding names to the prelude remains a non-breaking change. Adding new
|
|
|
|
|
+ predeclared names requires adding a keyword, with the same cost and
|
|
|
|
|
+ value tradeoffs regardless of whether the keyword names a library
|
|
|
|
|
+ declaration or introduces new language syntax.
|
|
|
|
|
+- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
|
|
|
|
|
+ - Syntax highlighting tools can easily distinguish between words with
|
|
|
|
|
+ special meaning and words with program-defined meaning.
|
|
|
|
|
+ - The meaning of core language constructs can be defined as a rewrite in
|
|
|
|
|
+ terms of `Core.<name>` without concern that `Core` may have some
|
|
|
|
|
+ different local interpretation.
|
|
|
|
|
+- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code)
|
|
|
|
|
+ - All C++ identifiers are nameable from Carbon code without conflicts.
|
|
|
|
|
+ Virtual functions introduced in Carbon can be overridden in Carbon
|
|
|
|
|
+ regardless of their name. C++ code can be migrated to Carbon even if its
|
|
|
|
|
+ name in C++ has special meaning in Carbon.
|
|
|
|
|
+- [Principle: Prefer providing only one way to do a given thing](/docs/project/principles/one_way.md)
|
|
|
|
|
+ - This proposal specifies that there is only one way to give words special
|
|
|
|
|
+ meaning in Carbon, and one way to resolve issues if that special meaning
|
|
|
|
|
+ conflicts with another desired meaning.
|
|
|
|
|
+
|
|
|
|
|
+## Future work
|
|
|
|
|
+
|
|
|
|
|
+### Package name `Cpp`
|
|
|
|
|
+
|
|
|
|
|
+The special package name `Cpp` that refers to code written in C++ is not made a
|
|
|
|
|
+keyword by this proposal, but this proposal is also not deciding that it should
|
|
|
|
|
+_not_ be a keyword. While this name has special meaning to the language, it's
|
|
|
|
|
+not predeclared in any context, so it's considered to be out of scope. A future
|
|
|
|
|
+proposal that describes the details of C++ import should determine whether this
|
|
|
|
|
+name becomes a keyword. Notably, making `Cpp` a keyword would also allow an
|
|
|
|
|
+`import Cpp` declaration to have custom syntax, which may be useful.
|
|
|
|
|
+
|
|
|
|
|
+### Package name `Main`
|
|
|
|
|
+
|
|
|
|
|
+The special package name `Main` that is currently reserved in all package name
|
|
|
|
|
+contexts is not made a keyword in this proposal either. There would be no
|
|
|
|
|
+meaning in making it a keyword, as it is never used as a special package name in
|
|
|
|
|
+Carbon source files. However, we could consider using an empty package name as
|
|
|
|
|
+the name of the main package, and unreserving the package name `Main`, if it
|
|
|
|
|
+becomes a concern that we reserve this name.
|
|
|
|
|
+
|
|
|
|
|
+## Alternatives considered
|
|
|
|
|
+
|
|
|
|
|
+### Have both predeclared identifiers and keywords
|
|
|
|
|
+
|
|
|
|
|
+We could provide both predeclared identifiers and keywords. Many languages
|
|
|
|
|
+follow this path. However, predeclared identifiers have some problems compared
|
|
|
|
|
+to keywords:
|
|
|
|
|
+
|
|
|
|
|
+- In order to locally declare a name matching a predeclared identifier, the
|
|
|
|
|
+ name would need to be shadowed.
|
|
|
|
|
+ - Such shadowing may be invalid, depending on how the name is used.
|
|
|
|
|
+ - Readability is harmed by using a name used as basic vocabulary with a
|
|
|
|
|
+ different, local meaning.
|
|
|
|
|
+ - Shadowing a predeclared identifier typically makes the original name
|
|
|
|
|
+ hard to access -- an alias or similar must be established in advance.
|
|
|
|
|
+- There need to be two different stories for how to deal with adding a new
|
|
|
|
|
+ word with special meaning to the language, depending on whether it is a
|
|
|
|
|
+ keyword.
|
|
|
|
|
+- For each word with special meaning, we must make an arbitrary decision as to
|
|
|
|
|
+ which kind it is, resulting in a largely meaningless distinction that
|
|
|
|
|
+ nonetheless is visible and would need to be known by developers in some
|
|
|
|
|
+ contexts.
|
|
|
|
|
+
|
|
|
|
|
+### Reserve words with a certain spelling
|
|
|
|
|
+
|
|
|
|
|
+We could reserve words with certain spellings for future use as keywords or as
|
|
|
|
|
+vendor extensions. Some languages do this:
|
|
|
|
|
+
|
|
|
|
|
+- C reserves words starting with an underscore followed by a capital letter or
|
|
|
|
|
+ an underscore.
|
|
|
|
|
+- C++ additionally reserves words containing a double underscore anywhere.
|
|
|
|
|
+- Python uses the `__name__` namespace for certain special names, and by
|
|
|
|
|
+ convention these names are reserved for that purpose.
|
|
|
|
|
+
|
|
|
|
|
+In Carbon we could accomplish this by saying that all words of the reserved
|
|
|
|
|
+forms are keywords, with no meaning ascribed to them yet.
|
|
|
|
|
+
|
|
|
|
|
+However, we do not have a clear need for such reserved words at this time, and
|
|
|
|
|
+we would not want to use such spellings when we do add language keywords later.
|
|
|
|
|
+Moreover, C++ programs frequently declare reserved words in practice, and we
|
|
|
|
|
+should expect the same in Carbon. Without enforcement, the names are not
|
|
|
|
|
+effectively reserved.
|
|
|
|
|
+
|
|
|
|
|
+If we find a need at a later time to introduce vendor-specific language
|
|
|
|
|
+extension keywords, we can revisit this, but should also consider alternatives
|
|
|
|
|
+such as a `k#foo` spelling to turn what is normally an identifier into a
|
|
|
|
|
+(potentially vendor-specific) keyword.
|