|
| 1 | +# No predeclared identifiers, `Core` is a keyword |
| 2 | + |
| 3 | +<!-- |
| 4 | +Part of the Carbon Language project, under the Apache License v2.0 with LLVM |
| 5 | +Exceptions. See /LICENSE for license information. |
| 6 | +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | +--> |
| 8 | + |
| 9 | +[Pull request](https://github.com/carbon-language/carbon-lang/pull/4864) |
| 10 | + |
| 11 | +<!-- toc --> |
| 12 | + |
| 13 | +## Table of contents |
| 14 | + |
| 15 | +- [Abstract](#abstract) |
| 16 | +- [Problem](#problem) |
| 17 | +- [Background](#background) |
| 18 | +- [Proposal](#proposal) |
| 19 | +- [Details](#details) |
| 20 | +- [Rationale](#rationale) |
| 21 | +- [Future work](#future-work) |
| 22 | + - [Package name `Cpp`](#package-name-cpp) |
| 23 | + - [Package name `Main`](#package-name-main) |
| 24 | +- [Alternatives considered](#alternatives-considered) |
| 25 | + - [Have both predeclared identifiers and keywords](#have-both-predeclared-identifiers-and-keywords) |
| 26 | + - [Reserve words with a certain spelling](#reserve-words-with-a-certain-spelling) |
| 27 | + |
| 28 | +<!-- tocstop --> |
| 29 | + |
| 30 | +## Abstract |
| 31 | + |
| 32 | +Introduce a principle that the Carbon language should not encroach on the |
| 33 | +developer's namespace. Satisfy this principle by making `Core` a keyword. |
| 34 | + |
| 35 | +## Problem |
| 36 | + |
| 37 | +Ongoing design work needs rules for how to expose types such as a primitive |
| 38 | +array type to Carbon code, and in particular, if we choose to make it available |
| 39 | +by default, whether that should be accomplished by a keyword or a predeclared |
| 40 | +identifier. |
| 41 | + |
| 42 | +## Background |
| 43 | + |
| 44 | +See the |
| 45 | +[Background section of the added principle](/docs/project/principles/namespace_cleanliness.md#background). |
| 46 | + |
| 47 | +## Proposal |
| 48 | + |
| 49 | +We choose to not have any predeclared identifiers in Carbon. If a word has |
| 50 | +special meaning to the language, then that word is a keyword, and a plain |
| 51 | +identifier with no special meaning is always available using raw identifier |
| 52 | +syntax. |
| 53 | + |
| 54 | +## Details |
| 55 | + |
| 56 | +See [the principle document](/docs/project/principles/namespace_cleanliness.md) |
| 57 | +for details of the added principle. In addition, we make one change and one |
| 58 | +clarification: |
| 59 | + |
| 60 | +- `Core` is changed from being an identifier that happens to be the name of |
| 61 | + the Carbon standard library, and happens to be predeclared in every source |
| 62 | + file as naming that library, to being a keyword. The keyword can only be |
| 63 | + used: |
| 64 | + |
| 65 | + - When importing the `Core` package. |
| 66 | + - When implementing the `Core` package as part of the language |
| 67 | + implementation. |
| 68 | + - As a keyword naming the `Core` package, much like the `package` keyword. |
| 69 | + |
| 70 | + The identifier `r#Core` can be used freely and does not conflict with the |
| 71 | + keyword. This includes use of `r#Core` as the name of a package. Language |
| 72 | + constructs that are defined in terms of entities in the `Core` package refer |
| 73 | + specifically to the package named with the _keyword_ `Core`, not to any |
| 74 | + other entity named `Core`. |
| 75 | + |
| 76 | +- The `self` keyword is now included in the list of keywords. It is already |
| 77 | + treated as a keyword by the toolchain. |
| 78 | + |
| 79 | +## Rationale |
| 80 | + |
| 81 | +- [Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem) |
| 82 | + - Code generation tools can have a uniform handling for all words with |
| 83 | + special meaning, with no need to alter the spelling of names from other |
| 84 | + languages. |
| 85 | + - Language tools can determine the meaning of `Core.<name>` without |
| 86 | + needing to do any name lookup or sophisticated analysis. |
| 87 | +- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution) |
| 88 | + - Migration between versions of Carbon with a changed set of reserved |
| 89 | + words can be done uniformly. |
| 90 | + - Adding names to the prelude remains a non-breaking change. Adding new |
| 91 | + predeclared names requires adding a keyword, with the same cost and |
| 92 | + value tradeoffs regardless of whether the keyword names a library |
| 93 | + declaration or introduces new language syntax. |
| 94 | +- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) |
| 95 | + - Syntax highlighting tools can easily distinguish between words with |
| 96 | + special meaning and words with program-defined meaning. |
| 97 | + - The meaning of core language constructs can be defined as a rewrite in |
| 98 | + terms of `Core.<name>` without concern that `Core` may have some |
| 99 | + different local interpretation. |
| 100 | +- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code) |
| 101 | + - All C++ identifiers are nameable from Carbon code without conflicts. |
| 102 | + Virtual functions introduced in Carbon can be overridden in Carbon |
| 103 | + regardless of their name. C++ code can be migrated to Carbon even if its |
| 104 | + name in C++ has special meaning in Carbon. |
| 105 | +- [Principle: Prefer providing only one way to do a given thing](/docs/project/principles/one_way.md) |
| 106 | + - This proposal specifies that there is only one way to give words special |
| 107 | + meaning in Carbon, and one way to resolve issues if that special meaning |
| 108 | + conflicts with another desired meaning. |
| 109 | + |
| 110 | +## Future work |
| 111 | + |
| 112 | +### Package name `Cpp` |
| 113 | + |
| 114 | +The special package name `Cpp` that refers to code written in C++ is not made a |
| 115 | +keyword by this proposal, but this proposal is also not deciding that it should |
| 116 | +_not_ be a keyword. While this name has special meaning to the language, it's |
| 117 | +not predeclared in any context, so it's considered to be out of scope. A future |
| 118 | +proposal that describes the details of C++ import should determine whether this |
| 119 | +name becomes a keyword. Notably, making `Cpp` a keyword would also allow an |
| 120 | +`import Cpp` declaration to have custom syntax, which may be useful. |
| 121 | + |
| 122 | +### Package name `Main` |
| 123 | + |
| 124 | +The special package name `Main` that is currently reserved in all package name |
| 125 | +contexts is not made a keyword in this proposal either. There would be no |
| 126 | +meaning in making it a keyword, as it is never used as a special package name in |
| 127 | +Carbon source files. However, we could consider using an empty package name as |
| 128 | +the name of the main package, and unreserving the package name `Main`, if it |
| 129 | +becomes a concern that we reserve this name. |
| 130 | + |
| 131 | +## Alternatives considered |
| 132 | + |
| 133 | +### Have both predeclared identifiers and keywords |
| 134 | + |
| 135 | +We could provide both predeclared identifiers and keywords. Many languages |
| 136 | +follow this path. However, predeclared identifiers have some problems compared |
| 137 | +to keywords: |
| 138 | + |
| 139 | +- In order to locally declare a name matching a predeclared identifier, the |
| 140 | + name would need to be shadowed. |
| 141 | + - Such shadowing may be invalid, depending on how the name is used. |
| 142 | + - Readability is harmed by using a name used as basic vocabulary with a |
| 143 | + different, local meaning. |
| 144 | + - Shadowing a predeclared identifier typically makes the original name |
| 145 | + hard to access -- an alias or similar must be established in advance. |
| 146 | +- There need to be two different stories for how to deal with adding a new |
| 147 | + word with special meaning to the language, depending on whether it is a |
| 148 | + keyword. |
| 149 | +- For each word with special meaning, we must make an arbitrary decision as to |
| 150 | + which kind it is, resulting in a largely meaningless distinction that |
| 151 | + nonetheless is visible and would need to be known by developers in some |
| 152 | + contexts. |
| 153 | + |
| 154 | +### Reserve words with a certain spelling |
| 155 | + |
| 156 | +We could reserve words with certain spellings for future use as keywords or as |
| 157 | +vendor extensions. Some languages do this: |
| 158 | + |
| 159 | +- C reserves words starting with an underscore followed by a capital letter or |
| 160 | + an underscore. |
| 161 | +- C++ additionally reserves words containing a double underscore anywhere. |
| 162 | +- Python uses the `__name__` namespace for certain special names, and by |
| 163 | + convention these names are reserved for that purpose. |
| 164 | + |
| 165 | +In Carbon we could accomplish this by saying that all words of the reserved |
| 166 | +forms are keywords, with no meaning ascribed to them yet. |
| 167 | + |
| 168 | +However, we do not have a clear need for such reserved words at this time, and |
| 169 | +we would not want to use such spellings when we do add language keywords later. |
| 170 | +Moreover, C++ programs frequently declare reserved words in practice, and we |
| 171 | +should expect the same in Carbon. Without enforcement, the names are not |
| 172 | +effectively reserved. |
| 173 | + |
| 174 | +If we find a need at a later time to introduce vendor-specific language |
| 175 | +extension keywords, we can revisit this, but should also consider alternatives |
| 176 | +such as a `k#foo` spelling to turn what is normally an identifier into a |
| 177 | +(potentially vendor-specific) keyword. |
0 commit comments