Logical operators
Table of contents
Overview
Carbon provides three operators to support logical operations on bool values:
andprovides a logical AND operation.x and yevaluates totrueif both operands aretrue.
orprovides a logical OR operation.x or yevaluates totrueif either operand istrue.
notprovides a logical NOT operation.not xevaluates totrueif the operand isfalse.
and and or are infix binary operators, and use short-circuit evaluation. not is a prefix unary operator.
Details
Precedence
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)) {
...
}
Associativity
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) {
...
}
Conversions
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 we decide that certain values, such as pointers or integers, should not be usable as the condition of an
ifwithout an explicit comparison against null or zero, then those values will also not be usable as the operand ofand,or, ornotwithout an explicit comparison. - If an extension point is provided to determine how to branch on the truth of a value in an
if(such as by supplying a conversion to abooltype), that extension point will also apply toand,or, andnot.
Overloading
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.
Alternatives considered
- Use punctuation spelling for all three operators
- Precedence of AND versus OR
- Precedence of NOT
- Punctuation form of NOT
- Two forms of NOT
- Repeated NOT
- AND and OR produce the decisive value
References
- Proposal #680: And, or, not.
- Proposal #702: Comparison operators.