Bläddra i källkod

Simplified package declaration for the `Main` package (#2550)

Make the preamble of simple programs more ergonomic, by removing the
`package Main` from the main package and removing the `package`
declaration
entirely from the main source file. Imports within a single package no
longer
need to, and are not permitted to, specify the package name.

Partially covers #2001 / #1136.
Covers #1869.
Supersedes #2265.
Addresses design idea #2323.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: josh11b <josh11b@users.noreply.github.com>
Richard Smith 2 år sedan
förälder
incheckning
ea982ad2c8
3 ändrade filer med 613 tillägg och 127 borttagningar
  1. 81 44
      docs/design/README.md
  2. 199 83
      docs/design/code_and_name_organization/README.md
  3. 333 0
      proposals/p2550.md

+ 81 - 44
docs/design/README.md

@@ -74,6 +74,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
     -   [Files, libraries, packages](#files-libraries-packages)
     -   [Package declaration](#package-declaration)
     -   [Imports](#imports)
+        -   [Same-package imports](#same-package-imports)
+        -   [Cross-package imports](#cross-package-imports)
     -   [Name visibility](#name-visibility)
     -   [Package scope](#package-scope)
     -   [Namespaces](#namespaces)
@@ -2095,16 +2097,12 @@ to coordinate to avoid name conflicts, but not across packages.
 
 ### Package declaration
 
-> **Note:** This is provisional, designs for a default package, making the
-> package name optional, and omitting the `package` declaration have not been
-> through the proposal process yet. See
-> [#2323](https://github.com/carbon-language/carbon-lang/issues/2323).
-
 Files start with an optional package declaration, consisting of:
 
--   the `package` keyword introducer,
--   an optional identifier specifying the package name,
--   optional `library` followed by a string with the library name,
+-   optionally, the `package` keyword followed by an identifier specifying the
+    package name,
+-   optionally, the `library` keyword followed by a string with the library
+    name,
 -   either `api` or `impl`, and
 -   a terminating semicolon (`;`).
 
@@ -2119,60 +2117,52 @@ package Geometry library "Shapes" api;
 
 Parts of this declaration may be omitted:
 
--   If the package name is omitted, as in `package library "Main" api;`, the
-    file contributes to the default package. No other package may import from
-    the default package.
+-   If the package keyword is not specified, as in `library "Widgets" api;`, the
+    file contributes to the `Main` package. No other package may import from the
+    `Main` package, and it cannot be named explicitly.
 
 -   If the library keyword is not specified, as in `package Geometry api;`, this
     file contributes to the default library.
 
--   If a file has no package declaration at all, it is the `api` file belonging
-    to the default package and default library. This is particularly for tests
-    and smaller examples. No other library can import this library even from
-    within the default package. It can be split across multiple `impl` files
-    using a `package impl;` package declaration.
+-   If both keywords are omitted, the package declaration must be omitted
+    entirely. In this case, the file is an `impl` file belonging to the default
+    library of the `Main` package, which implicitly has an empty `api` file.
+    This library is used to define the entry point for the program, and tests
+    and smaller examples may choose to reside entirely within this library. No
+    other library can import this library even from within the default package.
+
+If the default library of the `Main` package contains a function named `Run`,
+that function is the program entry point. Otherwise, the program's entry point
+may be defined in another language, such as by defining a C++ `main` function.
 
-A program need not use the default package, but if it does, it should contain
-the entry-point function. By default, the entry-point function is `Run` from the
-default package.
+> **Note:** Valid signatures for the entry point have not yet been decided.
 
 > References:
 >
 > -   [Code and name organization](code_and_name_organization)
 > -   Proposal
 >     [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
+> -   Proposal
+>     [#2550: Simplified package declaration for the main package](https://github.com/carbon-language/carbon-lang/pull/2550)
 
 ### Imports
 
-> **Note:** This is provisional, designs for making the package name optional
-> have not been through the proposal process yet. See
-> [#2001](https://github.com/carbon-language/carbon-lang/issues/2001).
+After the package declaration, files may include `import` declarations. The
+`import` keyword is followed by the package name, `library` followed by the
+library name, or both. If the library is omitted, the default library for that
+package is imported.
 
-After the package declaration, files may include `import` declarations. These
-include the package name and optionally `library` followed by the library name.
-If the library is omitted, the default library for that package is imported.
-
-```carbon
-// Import the "Vector" library from the
-// `LinearAlgebra` package.
-import LinearAlgebra library "Vector";
-// Import the default library from the
-// `ArbitraryPrecision` package.
-import ArbitraryPrecision;
-```
+All `import` declarations must appear before all other non-`package`
+declarations in the file.
 
-The syntax `import PackageName ...` introduces the name `PackageName` as a
-[`private`](#name-visibility) name naming the given package. It cannot be used
-to import libraries of the current package. Importing additional libraries from
-that package makes additional members of `PackageName` visible.
+#### Same-package imports
 
-Libraries from the current package are imported by omitting the package name.
+The package name must be omitted when importing a library from the current
+package.
 
 ```carbon
-// Import the "Vertex" library from the same package.
+// Import the "Vertex" library from the package containing this file.
 import library "Vertex";
-// Import the default library from the same package.
-import library default;
 ```
 
 The `import library ...` syntax adds all the public top-level names within the
@@ -2181,15 +2171,62 @@ given library to the top-level scope of the current file as
 [namespaces](#namespaces).
 
 Every `impl` file automatically imports the `api` file for its library.
+Attempting to perform an import of the current library is invalid.
 
-All `import` declarations must appear before all other non-`package`
-declarations in the file.
+```
+package MyPackage library "Widgets" impl;
+
+// ❌ Error, this import is performed implicitly.
+import MyPackage library "Widgets";
+```
+
+The default library for a package does not have a string name, and is instead
+named with the `default` keyword.
+
+```carbon
+// Import the default library from the same package.
+import library default;
+```
+
+It is an error to use the `import library default;` syntax in the `Main`
+package.
+
+#### Cross-package imports
+
+When the package name is specified, the `import` declaration imports a library
+from another package.
+
+```carbon
+package MyPackage impl;
+
+// Import the "Vector" library from the `LinearAlgebra` package.
+import LinearAlgebra library "Vector";
+
+// Import the default library from the `ArbitraryPrecision` package.
+import ArbitraryPrecision;
+```
+
+The syntax `import PackageName ...` introduces the name `PackageName` as a
+[`private`](#name-visibility) name naming the given package. Importing
+additional libraries from that package makes additional members of `PackageName`
+visible.
+
+It is an error to specify the name of the current package. The package name must
+be omitted when [importing from the same package](#same-package-imports).
+
+It is an error to specify `library default` in a package-qualified import.
+Instead, omit the `library` portion of the declaration.
+
+It is an error to specify the package name `Main`. Libraries in the `Main`
+package can only be imported from within that package.
 
 > References:
 >
 > -   [Code and name organization](code_and_name_organization)
 > -   Proposal
 >     [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
+> -   Proposal
+>     [#2550: Simplified package declaration for the main package](https://github.com/carbon-language/carbon-lang/pull/2550)
 
 ### Name visibility
 

+ 199 - 83
docs/design/code_and_name_organization/README.md

@@ -12,20 +12,21 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 -   [Goals and philosophy](#goals-and-philosophy)
 -   [Overview](#overview)
+    -   [Small programs](#small-programs)
+    -   [Packages](#packages)
     -   [Sizing packages and libraries](#sizing-packages-and-libraries)
-    -   [Imports](#imports)
 -   [Details](#details)
     -   [Source file introduction](#source-file-introduction)
     -   [Name paths](#name-paths)
         -   [`package` directives](#package-directives)
-    -   [Packages](#packages)
+    -   [Packages](#packages-1)
         -   [Shorthand notation for libraries in packages](#shorthand-notation-for-libraries-in-packages)
         -   [Package name conflicts](#package-name-conflicts)
     -   [Libraries](#libraries)
         -   [Exporting entities from an API file](#exporting-entities-from-an-api-file)
         -   [Granularity of libraries](#granularity-of-libraries)
         -   [Exporting namespaces](#exporting-namespaces)
-    -   [Imports](#imports-1)
+    -   [Imports](#imports)
         -   [Imports from the current package](#imports-from-the-current-package)
     -   [Namespaces](#namespaces)
         -   [Re-declaring imported namespaces](#re-declaring-imported-namespaces)
@@ -84,7 +85,79 @@ Important Carbon goals for code and name organization are:
 Carbon [source files](source_files.md) have a `.carbon` extension, such as
 `geometry.carbon`. These files are the basic unit of compilation.
 
-Each file begins with a declaration of which
+### Small programs
+
+For programs that fit into a single source file, no syntax is required to
+introduce the file. A very simple Carbon program can consist of a single file
+containing only a `Run` function:
+
+```
+fn Run() -> i32 {
+  return 6 * 9;
+}
+```
+
+However, as the program grows larger, it is desirable to split it across
+multiple source files. To support this,
+_libraries_<sup><small>[[define](/docs/guides/glossary.md#library)]</small></sup>
+can be written containing pieces of the program:
+
+```
+library "Colors" api;
+
+choice Color { Red, Green, Blue }
+
+fn ColorName(c: Color) -> String;
+```
+
+```
+library "Colors" impl;
+
+fn ColorName(c: Color) -> String {
+  match (c) {
+    case .Red => { return "Red"; }
+    case .Green => { return "Green"; }
+    case .Blue => { return "Blue"; }
+  }
+}
+```
+
+```
+// Make the "Colors" library visible here.
+import library "Colors";
+
+fn Run() {
+  Print(ColorName(Color.Red));
+}
+```
+
+A library is the basic unit of _dependency_. Separating code into multiple
+libraries can speed up the overall build while also making it clear which code
+is being reused.
+
+A library has a single `api` file which defines its interface, plus zero or more
+`impl` files that can provide any implementation details that were omitted from
+the `api` file. These files are distinguished by the `library` declaration
+ending with `api;` or `impl;`. By convention, implementation files also use a
+file extension of `.impl.carbon`.
+
+Separating a library into interface and implementation may help organize code as
+a library grows, or to let the build system distinguish between the dependencies
+of the API itself and its underlying implementation. Implementation files allow
+for code to be extracted out from the API file, while only being callable from
+other files within the library, including both API and implementation files.
+
+A source file that does not specify a library is implicitly within the default
+library. This is the library in which a Carbon `Run` function should reside.
+
+### Packages
+
+A program usually doesn't consist of only a single collection of source files
+developed by a team of people working together. In order to make it easy for
+different components of a program to be independently authored, Carbon supports
+_packages_ of code.
+
+Each source file in a package begins with a declaration of which
 _package_<sup><small>[[define](/docs/guides/glossary.md#package)]</small></sup>
 it belongs in. The package is the unit of _distribution_. The package name is a
 single identifier, such as `Geometry`. An example API file in the `Geometry`
@@ -94,28 +167,18 @@ package would start with:
 package Geometry api;
 ```
 
-A tiny package may consist of a single library with a single file, and not use
-any further features of the `package` keyword.
-
-It is often useful to use separate files for the API and its implementation.
-This may help organize code as a library grows, or to let the build system
-distinguish between the dependencies of the API itself and its underlying
-implementation. Implementation files allow for code to be extracted out from the
-API file, while only being callable from other files within the library,
-including both API and implementation files. Implementation files are marked by
-both naming the file to use an extension of `.impl.carbon` and instead start
-with:
+A tiny package may consist of a single library with a single `api` file. As with
+libraries, additional implementation files can be added to the package by using
+the `impl` keyword in the package declaration:
 
 ```
 package Geometry impl;
 ```
 
 However, as a package adds more files, it will probably want to separate out
-into multiple
-_libraries_<sup><small>[[define](/docs/guides/glossary.md#library)]</small></sup>.
-A library is the basic unit of _dependency_. Separating code into multiple
-libraries can speed up the overall build while also making it clear which code
-is being reused. For example, an API file adding the library `Shapes` to the
+into multiple libraries. These work exactly like the libraries described above.
+In fact, if no package is specified for a source file, it is implicitly part of
+the `Main` package. For example, an API file adding the library `Shapes` to the
 `Geometry` package, or `Geometry//Shapes` in
 [shorthand](#shorthand-notation-for-libraries-in-packages), would start with:
 
@@ -123,6 +186,43 @@ is being reused. For example, an API file adding the library `Shapes` to the
 package Geometry library "Shapes" api;
 ```
 
+This library can be imported within the same package by using:
+
+```
+import library "Shapes";
+```
+
+This will result in the public names declared in the `"Shapes"` library becoming
+visible in the importer, for example `Circle` might refer to a public type
+`Circle` declared in library `"Shapes"`.
+
+From a different package, this library can be imported by using:
+
+```
+import Geometry library "Shapes";
+```
+
+Unlike in a same-package import, this import only introduces the name
+`Geometry`, as a private name for the importer to use to refer to the `Geometry`
+package. Names declared within this package can be found as members of the name
+`Geometry`, for example `Geometry.Circle`. The `library` portion is optional in
+this syntax, and if omitted, the default (unnamed) library is imported.
+
+```
+// Imports the source file beginning `package Geometry api;`
+import Geometry;
+```
+
+The default library of a named package can be imported within that same package
+by using:
+
+```
+import library default;
+```
+
+This is not permitted within the `Main` package, because the default library of
+the `Main` package has no `api` file.
+
 As code becomes more complex, and users pull in more code, it may also be
 helpful to add
 _namespaces_<sup><small>[[define](/docs/guides/glossary.md#namespace)]</small></sup>
@@ -139,8 +239,8 @@ namespace TwoDimensional;
 struct TwoDimensional.Circle { ... };
 ```
 
-This scaling of packages into libraries and namespaces is how Carbon supports
-both small and large codebases.
+This scaling of programs into packages, libraries, and namespaces is how Carbon
+supports both small and large codebases.
 
 ### Sizing packages and libraries
 
@@ -171,28 +271,13 @@ other libraries within the package. However, doing so would also provide the
 transitive closure of build-time dependencies, and is likely to be discouraged
 in many cases.
 
-### Imports
-
-The `import` keyword supports reusing code from other files and libraries.
-
-For example, to use `Geometry.Circle` from the `Geometry//Shapes` library:
-
-```carbon
-import Geometry library "Shapes";
-
-fn Area(circle: Geometry.Circle) { ... };
-```
-
-The `library` keyword is optional for `import`, and its use should parallel that
-of `library` on the `package` of the code being imported.
-
 ## Details
 
 ### Source file introduction
 
 Every source file will consist of, in order:
 
-1. One `package` directive.
+1. Either a `package` directive, a `library` directive, or no introduction.
 2. A section of zero or more `import` directives.
 3. Source file body, with other code.
 
@@ -246,20 +331,35 @@ Breaking this apart:
     under [libraries](#libraries). If it instead had `impl`, this would be an
     implementation file.
 
-Because every file must have exactly one `package` directive, there are a couple
-important and deliberate side-effects:
-
--   Every file will be in precisely one library.
-    -   A library still exists even when there is no explicit library argument,
-        such as `package Geometry api;`. This could be considered equivalent to
-        `package Geometry library "" api;`, although we should not allow that
-        specific syntax as error-prone.
--   Every entity in Carbon will be in a namespace, even if its namespace path
-    consists of only the package name. There is no "global" namespace.
-    -   Every entity in a file will be defined within the namespace described in
-        the `package` directive.
-    -   Entities within a file may be defined in
-        [child namespaces](#namespaces).
+The syntax for `library` directives is the same, without the `package` portion:
+
+```regex
+library STRING (api|impl);
+```
+
+For example:
+
+```carbon
+library "PrimeGenerator" impl;
+```
+
+If the `package` portion is omitted, the file is implicitly part of the `Main`
+package, whose name cannot be written explicitly. If the `library` portion is
+omitted, the file is implicitly part of the default library, which does not have
+an identifier name. If neither a `package` directive nor a `library` directive
+is provided, the file is an `impl` file for the default library in the `Main`
+package. That library implicitly has an empty `api` file.
+
+As a consequence, every file is in exactly one library, which is always part of
+a package.
+
+Because every file is within a package, and packages act as top-level
+namespaces, every entity in Carbon will be in a namespace, even if its namespace
+path consists of only the package name. There is no "global" namespace.
+
+-   Every entity in a file will be defined within the namespace described in the
+    `package` directive.
+-   Entities within a file may be defined in [child namespaces](#namespaces).
 
 Files contributing to the `Geometry//Objects/FourSides` library must all start
 with `package Geometry library "Objects/FourSides"`, but will differ on
@@ -272,6 +372,11 @@ text. `PACKAGE//default` will refer to the name of the library used when no
 `library` argument is specified, although `PACKAGE` may also be used in
 situations where it is unambiguous that it still refers to the default library.
 
+The package name `Main` is always used implicitly and cannot appear as a package
+name within source code, but still appears in shorthand notation. For example,
+`Main//default` is the library that is expected to contain a Carbon `Run`
+function.
+
 It's recommended that libraries use a single `/` for separators where desired,
 in order to distinguish between the `//` of the package and `/` separating
 library segments. For example, `Geometry//Objects/FourSides` uses a single `/`
@@ -279,22 +384,17 @@ to separate the `Object/FourSides` library name.
 
 #### Package name conflicts
 
-Because the package also declares a namespace entity with the same name,
-conflicts with the package name are possible. We do not support packages
-providing entities with the same name as the package.
+Because an import of a package declares a namespace entity with the same name,
+conflicts with the package name are possible.
 
 For example, this is a conflict for `DateTime`:
 
 ```carbon
-package DateTime api;
+import DateTime;
 
-struct DateTime { ... };
+struct DateTime { ... }
 ```
 
-This declaration is important for [implementation files](#libraries), which
-implicitly import the library's API, because it keeps the package name as an
-explicit entity in source files.
-
 Note that [imported name conflicts](#package-and-library-name-conflicts) are
 handled differently.
 
@@ -394,17 +494,16 @@ libraries.
 
 #### Exporting namespaces
 
-Any entity may be marked with `api` except for namespace and package entities.
-That is, `api namespace Sha256;` is invalid code. Instead, namespaces are
-implicitly exported based on the name paths of other entities marked as `api`.
-
-For example, given this code:
+A namespace declared in an `api` file is only exported if it contains at least
+one `public` non-namespace name. For example, given this code:
 
 ```carbon
 package Checksums library "Sha" api;
 
-namespaces Sha256;
+namespace Sha256;
+namespace ImplementationDetails;
 
+private fn ImplementationDetails.ShaHelper(data: Bytes) -> Bytes;
 fn Sha256.HexDigest(data: Bytes) -> String { ... }
 ```
 
@@ -423,7 +522,8 @@ fn Process(data: Bytes) {
 ```
 
 In this example, the `Sha256` namespace is exported as part of the API
-implicitly.
+implicitly, but the name `Checksums.ImplementationDetails` is not available in
+the caller.
 
 ### Imports
 
@@ -432,13 +532,15 @@ implicitly.
 
 ```regex
 import IDENTIFIER (library NAME_PATH)?;
+import library NAME_PATH;
+import library default;
 ```
 
-An import declares a package entity named after the imported package, and makes
-API entities from the imported library available through it. The full name path
-is a concatenation of the names of the package entity, any namespace entities
-applied, and the final entity addressed. Child namespaces or entities may be
-[aliased](/docs/design/aliases.md) if desired.
+An import with a package name `IDENTIFIER` declares a package entity named after
+the imported package, and makes API entities from the imported library available
+through it. The full name path is a concatenation of the names of the package
+entity, any namespace entities applied, and the final entity addressed. Child
+namespaces or entities may be [aliased](/docs/design/aliases.md) if desired.
 
 For example, given a library:
 
@@ -475,9 +577,14 @@ automatically import the `api`, so a self-import should never be required.
 
 #### Imports from the current package
 
-Entities defined in the current file may be used without mentioning the package
-prefix. However, other symbols from the package must be imported and accessed
-through the package namespace just like symbols from any other package.
+An import without a package name imports the public names from the given library
+of the same package. It is not valid to import the default library of the `Main`
+package, because that library always has an empty `api`.
+
+Entities defined in the API of the current library and in imported libraries in
+the current package may be used without mentioning the package prefix. However,
+symbols from other packages must be imported and accessed through the package
+namespace.
 
 For example:
 
@@ -485,10 +592,11 @@ For example:
 package Geometry api;
 
 // This is required even though it's still in the Geometry package.
-import Geometry library "Shapes";
+import library "Shapes";
 
-// Circle must be referenced using the Geometry namespace of the import.
-fn GetArea(c: Geometry.Circle) { ... }
+// Circle is visible here. The name Geometry is not declared, so
+// Geometry.Circle is invalid.
+fn GetArea(c: Circle) { ... }
 ```
 
 ### Namespaces
@@ -524,7 +632,7 @@ the file's namespace. In the above example, after declaring
 
 #### Re-declaring imported namespaces
 
-Namespaces may exist on imported package entities, in addition to being declared
+Namespaces may exist in imported package entities, in addition to being declared
 in the current file. However, even if the namespace already exists in an
 imported library from the current package, the namespace must still be declared
 locally in order to add symbols to it.
@@ -535,7 +643,7 @@ For example, if the `Geometry//Shapes/ThreeSides` library provides the
 ```carbon
 package Geometry library "Shapes/FourSides" api;
 
-import Geometry library "Shapes/ThreeSides";
+import library "Shapes/ThreeSides";
 
 // This does not conflict with the existence of `Geometry.Shapes` from
 // `Geometry//Shapes/ThreeSides`, even though the name path is identical.
@@ -563,7 +671,7 @@ fn ParseData(data: TI.RawData);
 
 ### Package and library name conflicts
 
-Library name conflicts should not occur, because it's expected that a given
+Library name conflicts should be avoidable, because it's expected that a given
 package is maintained by a single organization. It's the responsibility of that
 organization to maintain unique library names within their package.
 
@@ -808,6 +916,12 @@ should be part of a larger testing plan.
     -   [Remove the `library` keyword from `package` and `import`](/proposals/p0107.md#remove-the-library-keyword-from-package-and-import)
     -   [Rename package concept](/proposals/p0107.md#rename-package-concept)
     -   [No association between the file system path and library/namespace](/proposals/p0107.md#no-association-between-the-file-system-path-and-librarynamespace)
+    -   [Require the use of the identifier `Main` in package declarations](/proposals/p2550.md#require-the-use-of-the-identifier-main-in-package-declarations)
+    -   [Permit the use of the identifier `Main` in package declarations](/proposals/p2550.md#permit-the-use-of-the-identifier-main-in-package-declarations)
+    -   [Make the main package be unnamed](/proposals/p2550.md#make-the-main-package-be-unnamed)
+    -   [Use a different name for the main package](/proposals/p2550.md#use-a-different-name-for-the-main-package)
+    -   [Use a different name for the entry point](/proposals/p2550.md#use-a-different-name-for-the-entry-point)
+    -   [Distinguish file scope from package scope](/proposals/p2550.md#distinguish-file-scope-from-package-scope)
 -   Libraries
     -   [Allow exporting namespaces](/proposals/p0107.md#allow-exporting-namespaces)
     -   [Allow importing implementation files from within the same library](/proposals/p0107.md#allow-importing-implementation-files-from-within-the-same-library)
@@ -833,7 +947,7 @@ should be part of a larger testing plan.
     -   [Block imports of libraries of a single package](/proposals/p0107.md#block-imports-of-libraries-of-a-single-package)
     -   [Broader imports, either all names or arbitrary code](/proposals/p0107.md#broader-imports-either-all-names-or-arbitrary-code)
     -   [Direct name imports](/proposals/p0107.md#direct-name-imports)
-    -   [Optional package names](/proposals/p0107.md#optional-package-names)
+    -   [Always include the package name in imports](/proposals/p2550.md#keep-the-package-name-in-imports)
 -   Namespaces
     -   [File-level namespaces](/proposals/p0107.md#file-level-namespaces)
     -   [Scoped namespaces](/proposals/p0107.md#scoped-namespaces)
@@ -842,3 +956,5 @@ should be part of a larger testing plan.
 
 -   Proposal
     [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
+-   Proposal
+    [#2550: Simplified package declaration for the main package](https://github.com/carbon-language/carbon-lang/pull/2550)

+ 333 - 0
proposals/p2550.md

@@ -0,0 +1,333 @@
+# Simplified package declaration for the `Main` package
+
+<!--
+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/2550)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Abstract](#abstract)
+-   [Problem](#problem)
+-   [Background](#background)
+-   [Proposal](#proposal)
+-   [Details](#details)
+-   [Rationale](#rationale)
+-   [Alternatives considered](#alternatives-considered)
+    -   [Require the use of the identifier `Main` in package declarations](#require-the-use-of-the-identifier-main-in-package-declarations)
+    -   [Permit the use of the identifier `Main` in package declarations](#permit-the-use-of-the-identifier-main-in-package-declarations)
+    -   [Distinguish file scope from package scope](#distinguish-file-scope-from-package-scope)
+    -   [Keep the package name in imports](#keep-the-package-name-in-imports)
+    -   [Make the main package be unnamed](#make-the-main-package-be-unnamed)
+    -   [Use a different name for the entry point](#use-a-different-name-for-the-entry-point)
+    -   [Use a different name for the main package](#use-a-different-name-for-the-main-package)
+-   [Acknowledgements](#acknowledgements)
+
+<!-- tocstop -->
+
+## Abstract
+
+Make the preamble of simple programs more ergonomic, by removing the
+`package Main` from the main package and removing the `package` declaration
+entirely from the main source file. Imports within a single package no longer
+need to, and are not permitted to, specify the package name.
+
+## Problem
+
+Every Carbon source file is required to start with a `package` declaration:
+
+```
+package Main impl;
+```
+
+This introduces complexity and syntactic overhead to very simple programs, such
+as might be encountered by beginners learning Carbon. This is also inconvenient
+for slide code and small examples in teaching material, where the author must
+choose between including boilerplate or providing an example that Carbon
+implementations will reject.
+
+In addition, imports within a single package are required to restate the name of
+the package:
+
+```
+package Geometry library "Shapes" api;
+import Geometry library "Points";
+```
+
+This creates additional syntactic overhead for a common operation, and misses
+the opportunity to visually distinguish between different categories of imports
+-- "our library" versus "their library". Additionally, under
+[#1136](https://github.com/carbon-language/carbon-lang/issues/1136), imports
+from the same package have different semantics than imports from a different
+package, so giving the two operations the same syntax seems confusing.
+
+Given that every package has an arbitrary, developer-selected identifier name,
+it is also unclear how to determine which package contains the entry point of
+the program. The name `Main` could be reserved for this, but no such decision
+has been made.
+
+## Background
+
+Proposal
+[#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107/files)
+introduced our current `package` syntax.
+
+In issue
+[#1869: What is the main entry point for execution? `Main` or `Run`?](https://github.com/carbon-language/carbon-lang/issues/1869)
+the leads decided that the entry point of a Carbon program is named `Main.Run`.
+That decision is implemented by this proposal.
+
+In issue
+[#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136),
+the leads decided that a package's name should not be injected into the scope of
+its files, and that same-package `import`s should not mention the package name.
+Those decisions are also implemented by this proposal. Note that other decisions
+were also made in #1136 regarding name access (`private`) and the behavior of
+unqualified name lookup that are not part of this proposal.
+
+## Proposal
+
+A Carbon program has a `Main` package, which is the package that contains the
+entry point of the program. The entry point is a function named `Run`.
+
+It is also possible to link Carbon libraries into programs written in other
+languages, and in particular, Carbon libraries can be used from C++ programs. In
+this case, there will be no Carbon `Run` function, and the C++ program will
+provide a `main` function that is used as the entry point.
+
+In the `Main` package, the package declaration does not explicitly specify a
+package name. The package declaration syntax becomes:
+
+-   `package` _Foo_ [`library "`_Bar_`"`] \(`api` | `impl`) `;`, unchanged from
+    #107, for a file that is part of a package other than the `Main` package.
+-   `library "`_Bar_`"` (`api` | `impl`) `;` for a library that is part of the
+    `Main` package.
+-   Omitted entirely for an `impl` file in the `Main` package that is not part
+    of a named library.
+
+There is no way to define an `api` file for the `Main` package that is not part
+of a named library -- there is no equivalent of `package Main api;`.
+
+The import syntax becomes:
+
+-   `import` _Foo_ `;` to import the default library of package _Foo_, or
+    `import` _Foo_ `library "`_Bar_`"` `;` to import library _Bar_. This
+    introduces the name _Foo_ in the current source file as a name for that
+    package, containing whatever subset of the package was imported. `Foo` is
+    not allowed to be the name of the current package.
+-   `import library "`_Bar_`";` to import library _Bar_ of the current package.
+    This introduces the names from that library at file scope. _Bar_ is not
+    allowed to be the name of the current library.
+-   `import library default;` to import the default library of the current
+    package. This is not allowed within the default library.
+
+It is an error to explicitly specify the package name `Main` in a package
+declaration or an import declaration. As a result, there is no way to import
+libraries of the `Main` package from any other package.
+
+It is permitted for a Carbon program to contain a source file that has no
+`package` declaration and does not contain a `Run` function -- or even to
+contain multiple such source files. Such a source file cannot implement any
+importable functionality, as there is no corresponding `api` file, but may still
+be useful to support Carbon features that have not yet been designed, such as:
+
+-   Global registration mechanisms.
+-   Some way of defining functions with well-known symbols, analogous to
+    `extern "C"` declarations in C++.
+
+## Details
+
+See design changes.
+
+## Rationale
+
+-   [Goal: Community and culture](/docs/project/goals.md#community-and-culture)
+    -   This change allows small complete programs and source files to be
+        discussed in Carbon forums without the overhead of `package`
+        declarations. Cumbersome top-level syntax hampers technical discussion.
+-   [Goal: Language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem)
+    -   Test cases for language tools are made unnecessarily verbose by the
+        mandatory inclusion of a `package` declaration and a `Main` function.
+        This proposal makes these components optional.
+-   [Goal: Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
+    -   Simple programs, such as `"hello, world"` examples written by beginners,
+        have less boilerplate.
+    -   Reduction of verbosity that is not contributing to increased
+        understanding of the program.
+-   [Goal: Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code)
+    -   This proposal explicitly acknowledges and permits the entry point for a
+        program that includes Carbon code to be written in a different language.
+    -   The use of the name `Main.Run` for the entry point is intended to be
+        similar enough to the use of the name `main` in C++ to be familiar.
+-   [Principle: Prefer providing only one way to do a given thing](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/principles/one_way.md)
+    -   Each `package` and `import` declaration has only one valid spelling. We
+        do not allow redundantly specifying the current package in an `import`,
+        nor using `library default` in any context where the `library` stanza
+        can be omitted with the same meaning, and we do not allow explicitly
+        writing a `package` declaration within the `Main` package.
+
+## Alternatives considered
+
+### Require the use of the identifier `Main` in package declarations
+
+Instead of the name `Main` being implied in `package` declarations, we could
+require it to be explicitly written:
+
+```
+package Main impl;
+import SimpleIO;
+
+fn Main() {
+  SimpleIO.Print("Hello, Carbon!");
+}
+```
+
+This would keep the Carbon language more consistent, and remove a special case.
+However, it would also increase verbosity in the simplest of programs, where the
+added verbosity has the most cost.
+
+### Permit the use of the identifier `Main` in package declarations
+
+We could allow the name `Main` to be used in package declarations and treat it
+the same as if the name were omitted, making the other forms merely shorthand.
+However, this would introduce a syntactic choice that doesn't correspond to any
+difference in intent, creating the opportunity for meaningless stylistic
+divergence, and we
+[prefer to leave only one syntactic choice](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/principles/one_way.md)
+in order to enforce consistency.
+
+### Distinguish file scope from package scope
+
+Under this proposal, the names from the current package that are visible, either
+by being declared locally or by being imported, are visible at the top level
+file scope. We could pick a different rule that distinguishes package scope from
+file scope, such as by introducing only locally-declared names into file scope
+and requiring a `PackageName.` prefix on all other names in the package.
+
+This was discussed at length in
+[#1136](https://github.com/carbon-language/carbon-lang/issues/1136). We found
+that distinguishing the package from the subset of the package visible at file
+scope led to problems that were more substantial than the potential
+simplification of treating imports of the current package as being the same as
+imports of any other package. See that issue for the full discussion.
+
+In [#1136](https://github.com/carbon-language/carbon-lang/issues/1136), it was
+also decided to add a `package.Name` syntax to allow shadowed names from the
+package scope to be referenced. That is not part of this proposal; until we add
+such a mechanism, its absence can be worked around by using private aliases:
+
+```
+fn Foo();
+private alias OuterFoo = Foo;
+
+class Bar {
+  fn Foo() {
+    // 🤷 Either ambiguous or calls `Bar.Foo`.
+    Foo();
+    // Calls `Foo` from package scope.
+    OuterFoo();
+  }
+}
+```
+
+### Keep the package name in imports
+
+We could consistently name the package targeted by an import in the `import`
+declaration:
+
+```
+package Foo api;
+import Foo library "Bar";
+```
+
+This would lead to a more uniform syntax and, as noted in
+[a very similar alternative considered by #107](/proposals/p0107.md#optional-package-names),
+would make it easier to search for all imports of a given library with a simple
+tool.
+
+There are two reasons to want to avoid this:
+
+-   Use of the same syntax suggests that same-package imports and cross-package
+    imports have the same semantics. But they do not: a same-package import
+    introduces the set of public names in the nominated library, whereas a
+    cross-package import of package `Bar` introduces exactly the name `Bar`.
+-   This would require writing a name for the `Main` package, in order to allow
+    libraries of that package to be imported within the same package. Adding
+    that name would provide a syntax to import those libraries from another
+    package, which we wanted to disallow.
+
+### Make the main package be unnamed
+
+We don't allow writing the name `Main` of the main package in `package`
+declarations nor in `import` declarations, so we could say that the main package
+has no name or has the empty name. We chose to give it a specific name for a few
+reasons:
+
+-   Conversationally and in documentation, it is clearer to talk about the main
+    package than the unnamed package, and we expect people to call it "the main
+    package" or similar regardless of which name we pick.
+-   There may still be reasons we need an identifier name to refer to this
+    package. For example, this need may arise in name mangling, in attributes,
+    in error messages, in conventions for naming source files, and in other
+    technical contexts that require an identifier referring to the package.
+
+One downside of picking a name is that it causes us to reserve an identifier and
+assign it special meaning, but we felt that using the name `Main` for any other
+package would be confusing, so this cost is small.
+
+Ultimately this decision was marginal, and the painter made the choice to use a
+named package in
+[#1869](https://github.com/carbon-language/carbon-lang/issues/1869).
+
+### Use a different name for the entry point
+
+We could use a variety of different names for the entry point and for the
+package that contains it. `Main` was the obvious first choice, as it is the name
+used in C and C++. However, we generally want to use verbs and verb phrases as
+function names, because functions describe actions and we find that verb phrases
+are easier to read and understand as function names as a result.
+
+Some other function names were considered but rejected:
+
+-   `Start` -- we preferred to use a word that describes the entire action of
+    the function, and the `Main.Run` function covers the complete execution of
+    the program, not just the beginning of that execution.
+-   `Entry` or `Entrypoint` -- same problems as `Start`, plus less discoverable,
+    potentially longer, not a familiar term to beginners, and not verbs.
+-   `Exec` or `Execute` -- we were concerned about a semantic collision between
+    the action of executing _some other_ program, as is performed by the C
+    `exec` function, and the action of executing the current program.
+
+See [#1869](https://github.com/carbon-language/carbon-lang/issues/1869) for more
+information about this decision.
+
+### Use a different name for the main package
+
+We considered other options for the main package name. The primary option
+considered was `Program`, but there were no decisive technical arguments to
+select one name over another. The painter selected `Main` with the following
+rough rationale:
+
+> -   We weren't using `Main` for the function name, so it seemed available.
+> -   Given that it is the "main package" and in fact contains the entry point,
+>     it didn't seem likely to have any confusion with `main` functions in other
+>     languages.
+> -   It is shorter than `Program`.
+> -   I guess that it will work better to indicate a conventional filename of
+>     `main.carbon`.
+> -   For folks looking for a `main` function, it may help them find our
+>     version.
+
+See [#1869](https://github.com/carbon-language/carbon-lang/issues/1869) for more
+information about this decision.
+
+## Acknowledgements
+
+Thanks to [Allison Poppe](https://github.com/acpoppe) for authoring proposal
+[#2265 Name of application entry point](https://github.com/carbon-language/carbon-lang/pull/2265)
+which explored another option for naming the entry point.