# 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.
