p0107.md 6.6 KB

Code and name organization

Pull request

Table of contents

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 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 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:

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:

    • 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:

    • 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:

    • 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:

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