Co-authored by: chandlerc - Based on [PR 22](https://github.com/carbon-language/carbon-lang/pull/83) - [Idea topic](https://forums.carbon-lang.dev/t/proposal-for-an-incomplete-rough-high-level-overview-ready-for-early-feedback/52) - [RFC](https://forums.carbon-lang.dev/t/rfc-an-incomplete-early-and-in-progress-overview-of-the-language-design/73) - [Decision announcement](https://forums.carbon-lang.dev/t/accepted-an-incomplete-early-and-in-progress-overview-of-the-language-design/110) This proposal should be considered a starting point of the language design. It's not intended to be final; language details may change. This is intended to offer a reasonable starting point for: - Example code. - Conceptualizing Carbon at a high level. - Reasonable, but not necessarily final, approaches to features in README.md. - If any idea is obviously bad, we can clean it up here. This proposal is not intended to achieve: - A whole language design. - This is way too much work for a single proposal; this is a skeletal framework only. - As we work on feature-specific designs, we may decide to use other approaches. That's fine: we only need somewhere to start. - The summaries in README.md may be expected to change over time. - Feature-specific files aren't intended to be well-written or comprehensive. They are a quick jot of prior thoughts. - We want to avoid getting stuck on language details that we should consider more carefully regardless. If you're passionate about a feature, please feel free to start a new proposal for it. - Each and every aspect of the suggested overview should be subject to careful examination and justification before it becomes a settled plan of record. Chandler started this with https://github.com/carbon-language/carbon-lang/pull/22. I've taken it over with the following changes: - More of a directory hierarchy. - Trying to thin out the main file (now README.md) to lighter summaries of features. - Details/rationale/alternatives should be in feature-specific files. - Draft files are linked as references where added. For an example of how we may proceed with feature-specific designs, see https://github.com/carbon-language/carbon-lang/pull/80. In this structure: - docs/design/README.md mentions interoperability, with a light overview. - The light overview is not yet in https://github.com/carbon-language/carbon-lang/pull/80. - docs/design/interoperability/README.md goes into more depth on interoperability, covering key points of the approach. - Individual files in docs/design/interoperability/* go into more depth on interoperability. Simple designs may not have a subdirectory. All current feature-specific designs do not -- they may be moved later.
3.8 KiB
Structs
Table of contents
TODO
This is a skeletal design, added to support the overview. It should not be treated as accepted by the core team; rather, it is a placeholder until we have more time to examine this detail. Please feel welcome to rewrite and update as appropriate.
Overview
Beyond simple tuples, Carbon of course allows defining named product types. This
is the primary mechanism for users to extend the Carbon type system and
fundamentally is deeply rooted in C++ and its history (C and Simula). We simply
call them structs rather than other terms as it is both familiar to existing
programmers and accurately captures their essence: they are a mechanism for
structuring data:
struct Widget {
var Int: x;
var Int: y;
var Int: z;
var String: payload;
}
Most of the core features of structures from C++ remain present in Carbon, but often using different syntax:
struct AdvancedWidget {
// Do a thing!
fn DoSomething(AdvancedWidget: self, Int: x, Int: y);
// A nested type.
struct NestedType {
// ...
}
private var Int: x;
private var Int: y;
}
fn Foo(AdvancedWidget: thing) {
thing.DoSomething(1, 2);
}
Here we provide a public object method and two private data members. The method
explicitly indicates how the object parameter is passed to it, and there is no
automatic scoping - you have to use self here. The self name is also a
keyword, though, that explains how to invoke this method on an object. This
member function accepts the object by value, which is easily expressed here
along with other constraints on the object parameter. Private members work the
same as in C++, providing a layer of easy validation of the most basic interface
constraints.
The type itself is a compile-time constant value. All name access is done with
the . notation. Constant members (including member types and member functions
which do not need an implicit object parameter) can be accessed via that
constant: AdvancedWidget.NestedType. Other members and member functions
needing an object parameter (or "methods") must be accessed from an object of
the type.
Some things in C++ are notably absent or orthogonally handled:
- No need for
staticfunctions, they simply don't take an initialselfparameter. - No
staticvariables because there are no global variables. Instead, can have scoped constants.
Open questions
self type
Requiring the type of self makes method declarations quite verbose. Unclear
what is the best way to mitigate this, there are many options. One is to have a
special Self type.
It may be interesting to consider separating the self syntax from the rest of
the parameter pattern as it doesn't seem necessary to inject all of the special
rules (covariance vs. contravariance, special pointer handling) for self into
the general pattern matching system.
Default access control level
The default access control level, and the options for access control, are pretty large open questions. Swift and C++ (especially w/ modules) provide a lot of options and a pretty wide space to explore here. If the default isn't right most of the time, access control runs the risk of becoming a significant ceremony burden that we may want to alleviate with grouped access regions instead of per-entity specifiers. Grouped access regions have some other advantages in terms of pulling the public interface into a specific area of the type.