Carbon provides three operators to support logical operations on bool values:
and provides a logical AND operation.
x and y evaluates to true if both operands are true.or provides a logical OR operation.
x or y evaluates to true if either operand is true.not provides a logical NOT operation.
not x evaluates to true if the operand is false.and and or are infix binary operators, and use
short-circuit evaluation.
not is a prefix unary operator.
and and or have very low precedence. When an expression appearing as the
condition of an if uses these operators unparenthesized, they are always the
lowest precedence operators in that expression.
These operators permit any reasonable operator that might be used to form a
bool value as a subexpression. In particular, comparison operators such as <
and == have higher precedence than and and or. However, the precedence of
and and or is not directly comparable with each other, so they cannot both
be used directly in an expression without parentheses.
not is higher precedence than and and or, but its precedence is
incomparable with most other operators, including comparison operators.
For example:
// ✅ Valid: `and` is lower precedence than the `<` or `==` operators.
if (n + m == 3 and not n < m) {
...
}
// The above is equivalent to:
if (((n + m) == 3) and (not (n < m))) {
...
}
// ❌ Invalid: `and` and `or` precedence is incomparable.
if (cond1 and cond2 or cond3) {
...
}
// ✅ Valid: Parentheses avoid the precedence check.
if (cond1 and (cond2 or cond3)) {
...
}
// ❌ Invalid: `not` precedence is incomparable with `==`.
if (not cond1 == cond2) {
...
}
// ❌ Invalid: `not` precedence is incomparable with `==`.
if (cond1 == not cond2) {
...
}
// ✅ Valid: Parentheses avoid the precedence check.
if (cond1 == (not cond2)) {
...
}
and and or are left-associative. A not expression cannot be the operand of
another not expression; not not b is an error without parentheses.
// ✅ Valid: `and` is left-associative, and precedence is fine.
if (not a and not b and not c) {
...
}
// The above is equivalent to:
if ((not a) and ((not b) and (not c))) {
...
}
// ✅ Valid: Parentheses avoid the `not` associativity error.
if (not (not a)) {
...
}
// ❌ Invalid: `not not` associativity requires parentheses.
if (not not a) {
...
}
TODO: This should be addressed through a standard
boolconversion design.
The operand of and, or, or not is converted to a bool value in the same
way as the condition of an if statement. In particular:
if without an explicit comparison against
null or zero, then those values will also not be usable as the operand of
and, or, or not without an explicit comparison.if (such as by supplying a conversion to a bool type),
that extension point will also apply to and, or, and not.The logical operators and, or, and not are not overloadable. As noted
above, any mechanism that allows types to customize how if treats them will
also customize how and, or, and not treats them.