if expressionsExpressions are the portions of Carbon syntax that produce values. Because types in Carbon are values, this includes anywhere that a type is specified.
fn Foo(a: i32*) -> i32 {
return *a;
}
Here, the parameter type i32*, the return type i32, and the operand *a of
the return statement are all expressions.
Expressions are interpreted based on a partial precedence ordering. Expression components which lack a relative ordering must be disambiguated by the developer, for example by adding parentheses; otherwise, the expression will be invalid due to ambiguity. Precedence orderings will only be added when it's reasonable to expect most developers to understand the precedence without parentheses.
The precedence diagram is defined thusly:
%%{init: {'themeVariables': {'fontFamily': 'monospace'}}}%%
graph BT
parens["(...)"]
braces["{...}"]
click braces "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#literals"
unqualifiedName["x"]
click unqualifiedName "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/README.md#unqualified-names"
memberAccess>"x.y<br>
x.(...)"]
click memberAccess "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/member_access.md"
as["x as T"]
click as "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/implicit_conversions.md"
not["not x"]
click not "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
comparison["x == y<br>
x != y<br>
x < y<br>
x <= y<br>
x > y<br>
x >= y"]
click comparison "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/comparison_operators.md"
and>"x and y"]
click and "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
or>"x or y"]
click or "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
if>"if x then y else z"]
click if "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/if.md"
expressionEnd["x;"]
memberAccess --> parens & braces & unqualifiedName
as & not --> memberAccess
comparison --> as
and & or --> comparison & not
if & expressionEnd --> and & or
The diagram's attributes are:
Each node represents a precedence group.
When an expression is composed from different precedence groups, the interpretation is determined by the precedence edges:
A precedence edge A --> B means that A is lower precedence than B, so A
can contain B without parentheses. For example, or --> not means that
not x or y is treated as (not x) or y.
Precedence edges are transitive. For example, or --> == --> as means
that or is lower precedence than as.
When an expression is composed from a single precedence group, the interpretation is determined by the associativity of the precedence group:
graph TD
non["Non-associative"]
left>"Left associative"]
+ and - are left-associative and in the same precedence
group, so a + b + c - d is treated as ((a + b) + c) - d.An unqualified name is a word that is not a
keyword and is not preceded by a period (.).
TODO: Name lookup rules for unqualified names.
A qualified name is a word that is prefixed by a period. Qualified names appear in the following contexts:
. wordDirect member access expressions: expression .
word
var x: auto = {.hello = 1, .world = 2};
^^^^^ ^^^^^ qualified name
^^^^^^ ^^^^^^ designator
x.hello = x.world;
^^^^^ ^^^^^ qualified name
^^^^^^^ ^^^^^^^ member access expression
Qualified names refer to members of an entity determined by the context in which the expression appears. For a member access, the entity is named by the expression preceding the period. In a struct literal, the entity is the struct type. For example:
package Foo api;
namespace N;
fn N.F() {}
fn G() {
// Same as `(Foo.N).F()`.
// `Foo.N` names namespace `N` in package `Foo`.
// `(Foo.N).F` names function `F` in namespace `N`.
Foo.N.F();
}
// `.n` refers to the member `n` of `{.n: i32}`.
fn H(a: {.n: i32}) -> i32 {
// `a.n` is resolved to the member `{.n: i32}.n`,
// and names the corresponding subobject of `a`.
return a.n;
}
fn J() {
// `.n` refers to the member `n of `{.n: i32}`.
H({.n = 5 as i32});
}
Member access expressions associate left-to-right. If the member name is more complex than a single word, an indirect member access expression can be used, with parentheses around the member name:
expression . ( member-access-expression )
interface I { fn F[me: Self](); }
class X {}
external impl X as I { fn F[me: Self]() {} }
// `x.I.F()` would mean `(x.I).F()`.
fn Q(x: X) { x.(I.F)(); }
Most expressions are modeled as operators:
| Category | Operator | Syntax | Function |
|---|---|---|---|
| Conversion | as |
x as T |
Converts the value x to the type T. |
| Logical | and |
x and y |
A short-circuiting logical AND: true if both operands are true. |
| Logical | or |
x or y |
A short-circuiting logical OR: true if either operand is true. |
| Logical | not |
not x |
Logical NOT: true if the operand is false. |
| Comparison | == |
x == y |
Equality: true if x is equal to y. |
| Comparison | != |
x != y |
Inequality: true if x is not equal to y. |
| Comparison | < |
x < y |
Less than: true if x is less than y. |
| Comparison | <= |
x <= y |
Less than or equal: true if x is less than or equal to y. |
| Comparison | > |
x > y |
Greater than: true if x is greater than to y. |
| Comparison | >= |
x >= y |
Greater than or equal: true if x is greater than or equal to y. |
When an expression appears in a context in which an expression of a specific type is expected, implicit conversions are applied to convert the expression to the target type.
Expressions can also be converted to a specific type using an
as expression.
fn Bar(n: i32);
fn Baz(n: i64) {
// OK, same as Bar(n as i32)
Bar(n);
}
if expressionsAn if expression chooses between two expressions.
fn Run(args: Span(StringView)) {
var file: StringView = if args.size() > 1 then args[1] else "/dev/stdin";
}
if expressions are analogous to ?: ternary expressions in C and C++.
Other expression documents will list more references; this lists references not noted elsewhere.
Other expression documents will list more references; this lists references not noted elsewhere.