mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
Design overview update part 1 (#1274)
Reorganizes the sections, and makes a pass filling in and updating the first sections including: types, functions, user-defined types. The following sections are left for part 2, including names, generics, and interop. Also some smaller updates to, not revisiting the text: `pattern_matching.md`, `control_flow/return.md`, and `lexical_conventions/numeric_literals.md` Co-authored-by: Geoff Romer <gromer@google.com> Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Geoff Romer
Chandler Carruth
parent
9007b3952d
commit
b17e69aefd
+1658
-723
File diff suppressed because it is too large
Load Diff
@@ -30,14 +30,14 @@ If the function returns a value to the caller, that value is provided by an
|
||||
expression in the return statement. For example:
|
||||
|
||||
```carbon
|
||||
fn Sum(a: Int, b: Int) -> Int {
|
||||
fn Sum(a: i32, b: i32) -> i32 {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
|
||||
When a return type is specified, a function must _always_ `return` before
|
||||
control flow can reach the end of the function body. In other words,
|
||||
`fn DoNothing() -> Int {}` would be invalid because execution will reach the end
|
||||
`fn DoNothing() -> i32 {}` would be invalid because execution will reach the end
|
||||
of the function body without returning a value.
|
||||
|
||||
### Returning empty tuples
|
||||
@@ -93,7 +93,7 @@ Returning expressions is not allowed while a `returned var` is in scope. For
|
||||
example:
|
||||
|
||||
```carbon
|
||||
fn MakeCircle(radius: Int) -> Circle {
|
||||
fn MakeCircle(radius: i32) -> Circle {
|
||||
returned var c: Circle;
|
||||
c.radius = radius;
|
||||
// `return c` would be invalid because `returned` is in use.
|
||||
@@ -106,7 +106,7 @@ If control flow exits the scope of a `returned` variable in any way other than
|
||||
`return` may again be used with expressions. For example:
|
||||
|
||||
```carbon
|
||||
fn MakePointInArea(Area area, Int preferred_x, Int preferred_y) -> Point {
|
||||
fn MakePointInArea(area: Area, preferred_x: i32, preferred_y: i32) -> Point {
|
||||
if (preferred_x >= 0 && preferred_y >= 0) {
|
||||
returned var p: Point = { .x = preferred_x, .y = preferred_y };
|
||||
if (area.Contains(p)) {
|
||||
@@ -148,7 +148,7 @@ declared by the caller. For example, here the `returned var vector` in
|
||||
copy:
|
||||
|
||||
```carbon
|
||||
fn CreateVector(x: Int, y: Int) -> Vector {
|
||||
fn CreateVector(x: i32, y: i32) -> Vector {
|
||||
returned var vector: Vector;
|
||||
vector.x = x;
|
||||
vector.y = y;
|
||||
|
||||
@@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
- [Overview](#overview)
|
||||
- [Details](#details)
|
||||
- [Integer literals](#integer-literals)
|
||||
- [Real number literals](#real-number-literals)
|
||||
- [Real-number literals](#real-number-literals)
|
||||
- [Digit separators](#digit-separators)
|
||||
- [Divergence from other languages](#divergence-from-other-languages)
|
||||
- [Alternatives considered](#alternatives-considered)
|
||||
@@ -29,13 +29,13 @@ The following syntaxes are supported:
|
||||
- `12345` (decimal)
|
||||
- `0x1FE` (hexadecimal)
|
||||
- `0b1010` (binary)
|
||||
- Real number literals
|
||||
- Real-number literals
|
||||
- `123.456` (digits on both sides of the `.`)
|
||||
- `123.456e789` (optional `+` or `-` after the `e`)
|
||||
- `0x1.2p123` (optional `+` or `-` after the `p`)
|
||||
- Digit separators (`_`) may be used, but only in conventional locations
|
||||
|
||||
Note that real number literals always contain a `.` with digits on both sides,
|
||||
Note that real-number literals always contain a `.` with digits on both sides,
|
||||
and integer literals never contain a `.`.
|
||||
|
||||
Literals are case-sensitive. Unlike in C++, literals do not have a suffix to
|
||||
@@ -65,7 +65,7 @@ the literal is `0`, the `0` begins a base specifier, or the next character is a
|
||||
decimal point (see below). No support is provided for octal literals, and any C
|
||||
or C++ octal literal (other than `0`) is invalid in Carbon.
|
||||
|
||||
### Real number literals
|
||||
### Real-number literals
|
||||
|
||||
Real numbers are written as a decimal or hexadecimal integer followed by a
|
||||
period (`.`) followed by a sequence of one or more decimal or hexadecimal
|
||||
@@ -81,23 +81,23 @@ is `p`, and the effect is to multiply the given value by
|
||||
2<sup>±_N_</sup>. The exponent suffix is optional for both decimal and
|
||||
hexadecimal real numbers.
|
||||
|
||||
Note that a decimal integer followed by `e` is not a real number literal. For
|
||||
Note that a decimal integer followed by `e` is not a real-number literal. For
|
||||
example, `3e10` is not a valid literal.
|
||||
|
||||
When a real number literal is interpreted as a value of a real number type, its
|
||||
When a real-number literal is interpreted as a value of a real-number type, its
|
||||
value is the representable real number closest to the value of the literal. In
|
||||
the case of a tie, the nearest value whose mantissa is even is selected.
|
||||
|
||||
The decimal real number syntax allows for any decimal fraction to be expressed
|
||||
-- that is, any number of the form _a_ x 10<sup>-_b_</sup>, where _a_ is an
|
||||
integer and _b_ is a non-negative integer. Because the decimal fractions are
|
||||
dense in the reals and the set of values of the real number type is assumed to
|
||||
be discrete, every value of the real number type can be expressed as a real
|
||||
dense in the reals and the set of values of the real-number type is assumed to
|
||||
be discrete, every value of the real-number type can be expressed as a real
|
||||
number literal. However, for certain applications, directly expressing the
|
||||
intended real number representation may be more convenient than producing a
|
||||
intended real-number representation may be more convenient than producing a
|
||||
decimal equivalent that is known to convert to the intended value. Hexadecimal
|
||||
real number literals are provided in order to permit values of binary floating
|
||||
or fixed point real number types to be expressed directly.
|
||||
real-number literals are provided in order to permit values of binary floating
|
||||
or fixed point real-number types to be expressed directly.
|
||||
|
||||
### Digit separators
|
||||
|
||||
@@ -108,7 +108,7 @@ respective condition:
|
||||
starting from the right. For example, `2_147_483_648`.
|
||||
- For hexadecimal integers, the digit separators shall occur every four digits
|
||||
starting from the right. For example, `0x7FFF_FFFF`.
|
||||
- For real number literals, digit separators can appear in the decimal and
|
||||
- For real-number literals, digit separators can appear in the decimal and
|
||||
hexadecimal integer portions (prior to the period and after the optional `e`
|
||||
or mandatory `p`) as described in the previous bullets. For example,
|
||||
`2_147.483648e12_345` or `0x1_00CA.FEF00Dp+24`
|
||||
|
||||
@@ -44,16 +44,16 @@ widely used in existing languages (Swift and Rust among others) and is currently
|
||||
under active investigation for C++. Carbon's `match` can be used as follows:
|
||||
|
||||
```
|
||||
fn Bar() -> (Int, (Float, Float));
|
||||
fn Foo() -> Float {
|
||||
fn Bar() -> (i32, (f32, f32));
|
||||
fn Foo() -> f32 {
|
||||
match (Bar()) {
|
||||
case (42, (Float x, Float y)) => {
|
||||
case (42, (x: f32, y: f32)) => {
|
||||
return x - y;
|
||||
}
|
||||
case (Int p, (Float x, Float _)) if (p < 13) => {
|
||||
case (p: i32, (x: f32, _: f32)) if (p < 13) => {
|
||||
return p * x;
|
||||
}
|
||||
case (Int p, auto _) if (p > 3) => {
|
||||
case (p: i32, _: auto) if (p > 3) => {
|
||||
return p * Pi;
|
||||
}
|
||||
default => {
|
||||
@@ -70,35 +70,35 @@ value, and execute that block. If none match, then it executes the default
|
||||
block.
|
||||
|
||||
Each `case` contains a pattern. The first part is a value pattern
|
||||
(`(Int p, auto _)` for example) followed by an optional boolean predicate
|
||||
introduced by the `if` keyword. The value pattern has to match, and then the
|
||||
predicate has to evaluate to true for the overall pattern to match. Value
|
||||
patterns can be composed of the following:
|
||||
(`(p: i32, _: auto)` for example) optionally followed by an `if` and boolean
|
||||
predicate. The value pattern has to match, and then the predicate has to
|
||||
evaluate to `true` for the overall pattern to match. Value patterns can be
|
||||
composed of the following:
|
||||
|
||||
- An expression (`42` for example), whose value must be equal to match.
|
||||
- An optional type (`Int` for example), followed by a `:` and either an
|
||||
identifier to bind to the value or the special identifier `_` to discard the
|
||||
value once matched.
|
||||
- A destructuring pattern containing a sequence of value patterns
|
||||
(`(Float x, Float y)`) which match against tuples and tuple like values by
|
||||
- An identifier to bind the value to, followed by a colon (`:`) and a type
|
||||
(`i32` for example). An underscore (`_`) may be used instead of the
|
||||
identifier to discard the value once matched.
|
||||
- A tuple destructuring pattern containing a tuple of value patterns
|
||||
(`(x: f32, y: f32)`) which match against tuples and tuple-like values by
|
||||
recursively matching on their elements.
|
||||
- An unwrapping pattern containing a nested value pattern which matches
|
||||
against a variant or variant-like value by unwrapping it.
|
||||
|
||||
In order to match a value, whatever is specified in the pattern must match.
|
||||
Using `auto` for a type will always match, making `auto _` the wildcard pattern.
|
||||
Using `auto` for a type will always match, making `_: auto` the wildcard
|
||||
pattern.
|
||||
|
||||
### Pattern matching in local variables
|
||||
|
||||
Value patterns may be used when declaring local variables to conveniently
|
||||
destructure them and do other type manipulations. However, the patterns must
|
||||
match at compile time which is why the boolean predicate cannot be used
|
||||
directly.
|
||||
match at compile time, so they can't use an `if` clause.
|
||||
|
||||
```
|
||||
fn Bar() -> (Int, (Float, Float));
|
||||
fn Foo() -> Int {
|
||||
var (Int p, auto _) = Bar();
|
||||
fn Bar() -> (i32, (f32, f32));
|
||||
fn Foo() -> i32 {
|
||||
var (p: i32, _: auto) = Bar();
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user