mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 10:54:49 +01:00
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>
This commit is contained in:
co-authored by
Chandler Carruth
parent
df9494a948
commit
5943208f75
@@ -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.
|
||||
|
||||
As a consequence, every file is in exactly one library, which is always part of
|
||||
a package.
|
||||
#### `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`.
|
||||
|
||||
#### 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)
|
||||
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user