Explorar el Código

Change Main//default to an api file (#3403)

When there is no `package` directive, default to `Main//default api`
instead of
`Main//default impl`. This means:

- The extension will be `.carbon`, not `.impl.carbon`.
- There can only be one such file when compiling.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Jon Ross-Perkins hace 2 años
padre
commit
5943208f75
Se han modificado 2 ficheros con 137 adiciones y 18 borrados
  1. 38 18
      docs/design/code_and_name_organization/README.md
  2. 99 0
      proposals/p3403.md

+ 38 - 18
docs/design/code_and_name_organization/README.md

@@ -18,8 +18,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 -   [Details](#details)
     -   [Source file introduction](#source-file-introduction)
     -   [Name paths](#name-paths)
-        -   [`package` directives](#package-directives)
     -   [Packages](#packages-1)
+        -   [`package` directives](#package-directives)
+        -   [`library` directives](#library-directives)
+        -   [`Main//default`](#maindefault)
+        -   [Files and libraries](#files-and-libraries)
         -   [Shorthand notation for libraries in packages](#shorthand-notation-for-libraries-in-packages)
         -   [Package name conflicts](#package-name-conflicts)
     -   [Libraries](#libraries)
@@ -220,8 +223,9 @@ 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.
+The `Main` package can only be imported from other parts of the `Main` package,
+never other packages. Importing `Main//default` is invalid, regardless of which
+package is used.
 
 As code becomes more complex, and users pull in more code, it may also be
 helpful to add
@@ -297,10 +301,10 @@ IDENTIFIER(\.IDENTIFIER)*
 
 Name conflicts are addressed by [name lookup](/docs/design/name_lookup.md).
 
-#### `package` directives
-
 ### Packages
 
+#### `package` directives
+
 The `package` directive's syntax may be loosely expressed as a regular
 expression:
 
@@ -324,13 +328,20 @@ Breaking this apart:
         words, if the file declares `struct Line`, that may be used from within
         the file as both `Line` directly and `Geometry.TwoDimensional.Line`
         using the `Geometry` package entity created by the `package` keyword.
+    -   `Main` is invalid for use as the package name. `Main` libraries must be
+        defined by either the [`library` directive](#library-directives) or the
+        [`Main//default`](#maindefault) rule.
 -   When the optional `library` keyword is specified, sets the name of the
     library within the package. In this example, the
     `Geometry//Objects/FourSides` library will be used.
+    -   If the `library` portion is omitted, the file is implicitly part of the
+        default library, which does not have a string name.
 -   The use of the `api` keyword indicates this is an API files as described
     under [libraries](#libraries). If it instead had `impl`, this would be an
     implementation file.
 
+#### `library` directives
+
 The syntax for `library` directives is the same, without the `package` portion:
 
 ```regex
@@ -343,15 +354,18 @@ For example:
 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.
+If the `library` directive is used, the file is implicitly part of the `Main`
+package, whose name cannot be written explicitly.
+
+#### `Main//default`
+
+If neither a `package` directive nor a `library` directive is provided, the file
+is an `api` file for `Main//default`. An `impl` cannot be provided for
+`Main//default`.
 
-As a consequence, every file is in exactly one library, which is always part of
-a package.
+#### Files and libraries
+
+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
@@ -538,9 +552,13 @@ import library default;
 
 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.
+through it. `Main` cannot be imported from other packages; in other words, only
+`import library NAME_PATH` syntax can be used to import from `Main`. Imports of
+`Main//default` are invalid.
+
+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:
 
@@ -578,8 +596,7 @@ automatically import the `api`, so a self-import should never be required.
 #### Imports from the current 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`.
+of the same package.
 
 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,
@@ -922,6 +939,7 @@ should be part of a larger testing plan.
     -   [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)
+    -   [Default to `Main//default impl` instead of `Main//default api`](/proposals/p3403.md#default-to-maindefault-impl-instead-of-maindefault-api)
 -   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)
@@ -958,3 +976,5 @@ should be part of a larger testing plan.
     [#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)
+-   Proposal
+    [#3403: Change Main//default to an api file](https://github.com/carbon-language/carbon-lang/pull/3403)

+ 99 - 0
proposals/p3403.md

@@ -0,0 +1,99 @@
+# Change Main//default to an api file
+
+<!--
+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/3403)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Abstract](#abstract)
+-   [Problem](#problem)
+-   [Background](#background)
+-   [Proposal](#proposal)
+-   [Rationale](#rationale)
+-   [Alternatives considered](#alternatives-considered)
+    -   [Default to `Main//default impl` instead of `Main//default api`](#default-to-maindefault-impl-instead-of-maindefault-api)
+
+<!-- tocstop -->
+
+## Abstract
+
+When there is no `package` directive, default to `Main//default api` instead of
+`Main//default impl`. This has two user-visible consequences:
+
+-   The extension will be `.carbon`, not `.impl.carbon`.
+-   Only one `Main//default api` is allowed.
+
+## Problem
+
+[Code and name organization](/docs/design/code_and_name_organization/#libraries)
+says:
+
+-   API filenames must have the `.carbon` extension. They must not have a
+    `.impl.carbon` extension.
+-   Implementation filenames must have the `.impl.carbon` extension.
+
+The `Main//default` library is currently specified as an `impl` file. This means
+that it should be something like `main.impl.carbon`.
+
+## Background
+
+More generally in Carbon, a single-file library can be an `api` file, not an
+`impl` file. This comes as a side-effect from `impl` files implicitly importing
+the `api`, which would fail if there were an `impl` file without an `api`. On
+the other hand, there is no requirement that an `api` file have an `impl`.
+
+Proposal
+[#2550: Simplified package declaration for the `Main` package](https://github.com/carbon-language/carbon-lang/pull/2550)
+chose `impl` as the default, providing an empty `api` file that cannot otherwise
+be imported. The proposal doesn't provide rationale for this choice; it likely
+wasn't considered key to the proposal.
+
+In C++, we often see `main.cpp`. This might be where the `impl` choice for
+`Main//default` comes from, as it has a more equivalent feel.
+
+## Proposal
+
+Omitting the package directive means `Main//default api`, rather than `impl`. As
+a consequence:
+
+-   The `.carbon` extension applies instead of the `.impl.carbon` extension.
+-   An `api` can only be defined once, so there is a limit of one such file per
+    executable.
+
+Mentions of `Main//default api` as being an empty file are removed.
+
+The rules preventing use of `Main//default` in `package`, `library`, or `import`
+remain. The library can only be defined by omission of `package` and `library`,
+and cannot be imported.
+
+## Rationale
+
+-   [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
+
+    -   Writing `Run` logic in a `main.carbon` file is expected to be more
+        intuitive than `main.impl.carbon`.
+
+## Alternatives considered
+
+### Default to `Main//default impl` instead of `Main//default api`
+
+`Main//default impl`, the status quo, is now a declined alternative. Key
+considerations are:
+
+-   Using `Main//default api` is consistent with single-file libraries in other
+    contexts.
+-   `main.carbon` is preferred over `main.impl.carbon`, and using
+    `Main//default api` allows the `main.carbon` extension without
+    special-casing the file extension choices.
+-   The special-case definition of `Main//default api` as an empty file is no
+    longer needed.
+-   Being able to have multiple `Main//default impl` files is of limited
+    utility. `Run` could only be defined in one such file, and the
+    `Main//default api` was defined as empty so no sharing was allowed.