Browse Source

Principle: All APIs are library APIs (#1280)

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Geoff Romer 3 năm trước cách đây
mục cha
commit
bc40bdc279
2 tập tin đã thay đổi với 188 bổ sung0 xóa
  1. 104 0
      docs/project/principles/library_apis_only.md
  2. 84 0
      proposals/p1280.md

+ 104 - 0
docs/project/principles/library_apis_only.md

@@ -0,0 +1,104 @@
+# Principle: All APIs are library APIs
+
+<!--
+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
+-->
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Background](#background)
+-   [Principle](#principle)
+-   [Applications of this principle](#applications-of-this-principle)
+-   [Exceptions](#exceptions)
+-   [Alternatives considered](#alternatives-considered)
+
+<!-- tocstop -->
+
+## Background
+
+Every major modern programming language comes with a standard library, which
+consists of APIs that are not part of the core language, but instead are written
+in the language (although their implementations may not be). However, different
+languages draw the boundary between language and library in different places.
+For example, Go's `map` type is built into the core language, whereas the C++
+equivalent, `std::unordered_map`, is part of the standard library. In Swift,
+even fundamental types like integers and pointers are part of the standard
+library; there are no truly "built in" types.
+
+These decisions can have important consequences for the design of the language.
+For example, many important features of C++, such as move semantics, variadics,
+and coroutines, were motivated largely by their anticipated uses in a small set
+of standard library types. In a language with a different design philosophy,
+those types could have been built into the core language. This would probably
+have substantially simplified the language, and made those types available
+faster. However, that would have come at the cost of less flexibility for users
+outside the common case.
+
+## Principle
+
+In Carbon, every public function is declared in some Carbon `api` file, and
+every public `interface`, `impl`, and first-class type is defined in some Carbon
+`api` file. In some cases, the bodies of public functions will not be defined as
+Carbon code, or will be defined as hybrid Carbon code using intrinsics that
+aren't available to ordinary Carbon code. However, we will try to minimize those
+situations.
+
+Thus, even "built-in" APIs can be used like user-defined APIs, by importing the
+appropriate library and using qualified names from that library, relying on the
+ordinary semantic rules for Carbon APIs.
+
+## Applications of this principle
+
+We expect Carbon to have a special "prelude" library that is implicitly imported
+by all Carbon source files, and there might be a special name lookup rule to
+allow the names in the prelude to be used unqualified. However, in accordance
+with this principle, they will remain available to ordinary qualified name
+lookup as well.
+
+According to the resolutions of
+[#543](https://github.com/carbon-language/carbon-lang/issues/543) and
+[#750](https://github.com/carbon-language/carbon-lang/issues/543), Carbon will
+have a substantial number of type keywords, such as `i32`, `f64`, and `bool`.
+However, these keywords will all be aliases for ordinary type names, such as
+`Carbon.Int(32)`, `Carbon.Float(64)`, and `Carbon.Bool`. Furthermore, all
+arithmetic and logical operators will be overloadable, so that those types can
+be defined as class types. The member function bodies for these types will be
+probably not be implemented in Carbon, but this principle applies only to
+function declarations, not function definitions.
+
+Similarly, a pointer type such as `Foo*` will be an alias for some library class
+type, for example `Carbon.Ptr(Foo)`. As a result, Carbon will support
+overloading pointer operations like `->` and unary `*`.
+
+All Carbon operations that use function-style syntax, such as `sizeof()` and
+`decltype()` in C++, will be standard library functions. As above, in some cases
+we may choose to alias those functions with keywords, and the function bodies
+may not be defined in Carbon.
+
+## Exceptions
+
+This principle applies to types only if they are _first-class_, meaning that
+they can be the types of run-time variables, function parameters, and return
+values. Carbon's type system will probably also include some types whose usage
+is more restricted, and this principle will not apply to them. Most importantly,
+function types might not be first-class types, in which case they need not be
+library types.
+
+The logic for translating a literal expression to a value of the appropriate
+type is arguably part of that type's public API, but will not be part of that
+type's class definition.
+
+Tuple types will probably not fully conform to this principle, because doing so
+would be circular: there is no way to name a tuple type that doesn't rely on
+tuple syntax, and no way to define a class body for a tuple type that doesn't
+contain tuple patterns. However, we will strive to ensure that it is possible to
+define a parameterized class type within Carbon that supports all the same
+operations as built-in tuple types.
+
+## Alternatives considered
+
+-   [Built-in primitive types](/proposals/p1280.md#built-in-primitive-types)

+ 84 - 0
proposals/p1280.md

@@ -0,0 +1,84 @@
+# Principle: All APIs are library APIs
+
+<!--
+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/1280)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Problem](#problem)
+-   [Background](#background)
+-   [Proposal](#proposal)
+-   [Details](#details)
+-   [Rationale](#rationale)
+-   [Alternatives considered](#alternatives-considered)
+    -   [Built-in primitive types](#built-in-primitive-types)
+
+<!-- tocstop -->
+
+## Problem
+
+We need a clear and consistent "division of labor" between the core language and
+the standard library.
+
+## Background
+
+See
+[the principle doc](/docs/project/principles/library_apis_only.md#background).
+
+See also [#57](https://github.com/carbon-language/carbon-lang/pull/57), a
+previous iteration of a similar idea.
+
+## Proposal
+
+In Carbon, every public function will be declared in some Carbon `api` file, and
+every public `interface`, `impl`, and first-class type will be defined in some
+Carbon `api` file. In some cases, the bodies of public functions will not be
+defined as Carbon code, or will be defined as hybrid Carbon code using
+intrinsics that aren't available to ordinary Carbon code. However, we will try
+to minimize those situations.
+
+Thus, even "built-in" APIs can be used like user-defined APIs, by importing the
+appropriate library and using qualified names from that library, relying on the
+ordinary semantic rules for Carbon APIs.
+
+## Details
+
+See [the principle doc](/docs/project/principles/library_apis_only.md).
+
+## Rationale
+
+This principle facilitates
+[software evolution](/docs/project/goals.md#software-and-language-evolution), by
+helping to ensure that code written in terms of a Carbon-provided type can be
+migrated to use a suitable user-defined type instead. It also facilitates
+evolution of the language itself, by enabling more of that evolution to take
+place in library code, which doesn't require compiler expertise.
+
+This principle helps make Carbon code
+[easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write),
+because user-defined APIs can match the ergonomics of language-defined APIs, and
+the syntax, language rules, and core concepts are consistent between the two.
+
+This principle indirectly helps Carbon support
+[performance-critical software](/docs/project/goals.md#performance-critical-software):
+by using Carbon's API abstraction mechanisms for even the most fundamental
+types, we ensure that those mechanisms do not impose any performance overhead.
+
+## Alternatives considered
+
+### Built-in primitive types
+
+We could follow the general outline of C++, where arithmetic and pointer types
+are built-in. However, that would substantially erode the advantages outlined
+above. We expect Carbon to have multiple kinds of pointers (for example, to
+represent different kinds of ownership), and multiple kinds of arithmetic types
+(for example, to handle overflow in different ways). They can't all be built-in,
+so putting even the common-case types in the library helps ensure that Carbon
+has enough expressive power for the uncommon-case library types.