# Code and name organization

<!--
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/107)

<!-- toc -->

## Table of contents

-   [Problem](#problem)
-   [Proposal](#proposal)
    -   [Out-of-scope issues](#out-of-scope-issues)
-   [Open questions for the decision](#open-questions-for-the-decision)
    -   [Should we switch to a library-oriented structure that's package-agnostic?](#should-we-switch-to-a-library-oriented-structure-thats-package-agnostic)
    -   [Should there be a tight association between file paths and packages/libraries?](#should-there-be-a-tight-association-between-file-paths-and-packageslibraries)
-   [Justification](#justification)

<!-- tocstop -->

## Problem

How do developers store code for the compiler, and access it for reuse?

## Proposal

Adopt an approach with tiered files, libraries, packages and namespaces in the
design.

### Out-of-scope issues

Related issues that are out-of-scope for this proposal are:

-   Access control: while there is some implicit access control from interface
    vs implementation considerations for libraries, they are more about
    addressing circular dependencies in code.

-   Aliasing implementation: while the `alias` keyword is critical to how easy
    or difficult refactoring is, it should be designed on its own.

-   Compilation details: this proposal sets up a framework that should enable
    well-designed compilation, but does not set about to design how compilation
    will work.

-   File-private identifiers: Something similar to C++ `static` functions may
    exist. However, that will be addressed separately.

-   Incremental migration and unused imports: incrementally migrating a
    declaration from one library to another might require an intermediate state
    where callers import both libraries, with consequent issues. However, it may
    also not require such. Whether it does, or whether tooling needs to be added
    to support the specific intermediary state of transitional, unused imports,
    is out of scope.

-   Name lookup, including addressing conflicting names between imports and
    names in the current file: the name lookup design is likely to address this
    better, including offering syntax that could refer to it if needed.

    -   After discussion, we believe we do not need to support package renaming.
        However, that final decision should be based on name lookup addressing
        the issue, as implications need to be considered more deeply.

-   Package management: while we want to choose syntax that won't impose
    barriers on building package management into Carbon, we should not make
    assumptions about how package management should work.

-   Prelude package, or fundamentals: while we've discussed how to handle name
    lookup for things like `Int32`, this proposal mainly lays out a framework
    where options for addressing that are possible.

This proposal should not be interpreted as addressing these issues. A separate
discussion of these issues will remain necessary.

## Open questions for the decision

Extended open question comparisons may be found in
[the examples doc](https://docs.google.com/document/d/1J8GX9uw5AxBz5Q22MLHJOfzLq4WJqKL-q1VwnKGHG-k/edit#)
in addition to the `code_and_organization.md` alternatives section.

### Should we switch to a library-oriented structure that's package-agnostic?

**Decision:** No.

Right now, the `package` syntax is very package-oriented. We could instead
eliminate package semantics from code and organization, relying only on
libraries and removing the link to distribution. This is the
[collapse the package concept into libraries](/docs/design/code_and_name_organization.md#collapse-the-package-concept-into-libraries)
alternative.

Does the core team agree with the approach to packages and libraries? If not,
does the alternative capture what the core team wants to be turned into the
proposal, or is some other approach preferred?

### Should there be a tight association between file paths and packages/libraries?

**Decision:** Make paths correspond to libraries for API files, not impl files.
Keep `package`.

Right now, the `package` syntax requires the package's own name be repeated
through code. This touches on a couple alternatives:

-   Strict association between the file system path and library/namespace
-   [Referring to the package as `package`](/docs/design/code_and_name_organization.md#referring-to-the-package-as-package)

The end result of taking both alternatives would be that:

-   The `package` and `library` would no longer need to be specified on the
    first line.
    -   The `import` would still need a `library`.
-   The `package` keyword would always be used to refer to the current package.
    -   Referring to the current package by name would be disallowed, to allow
        for easier renames of conflicting package names.

## Justification

-   [Software and language evolution](/docs/project/goals.md#software-and-language-evolution):

    -   The syntax and interactions between `package` and `import` should enable
        moving code between files and libraries with fewer modifications to
        callers, easing maintenance of large codebases.

        -   In C++ terms, `#include` updates are avoidable when moving code
            around.

-   [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write):

    -   By setting up imports so that each name in a file is unique and refers
        to the source package, we make the meaning of symbols clear and easier
        to understand.

    -   The proposed `namespace` syntax additionally makes it clear when the
        package's default namespace is not being used.

        -   This is in contrast to C++ namespaces, where the entire body of code
            above the line of code in question may be used to start a namespace.

    -   Clearly marking interfaces will make it easier for both client code and
        IDE tab completion to more easily determine which APIs can be used from
        a given library.

-   [Fast and scalable development](/docs/projects/goals.md#fast-and-scalable-development):

    -   The structure of libraries and imports should help enable separate
        compilation, particularly improving performance for large codebases.

-   [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code):

    -   The syntax of `import` should enable extending imports for use in
        interoperability code.
