|
| 1 | +# Logical operators |
| 2 | + |
| 3 | +<!-- |
| 4 | +Part of the Carbon Language project, under the Apache License v2.0 with LLVM |
| 5 | +Exceptions. See /LICENSE for license information. |
| 6 | +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | +--> |
| 8 | + |
| 9 | +<!-- toc --> |
| 10 | + |
| 11 | +## Table of contents |
| 12 | + |
| 13 | +- [Overview](#overview) |
| 14 | +- [Details](#details) |
| 15 | + - [Precedence](#precedence) |
| 16 | + - [Associativity](#associativity) |
| 17 | + - [Conversions](#conversions) |
| 18 | + - [Overloading](#overloading) |
| 19 | +- [Alternatives considered](#alternatives-considered) |
| 20 | +- [References](#references) |
| 21 | + |
| 22 | +<!-- tocstop --> |
| 23 | + |
| 24 | +## Overview |
| 25 | + |
| 26 | +Carbon provides three operators to support logical operations on `bool` values: |
| 27 | + |
| 28 | +- `and` provides a logical AND operation. |
| 29 | + - `x and y` evaluates to `true` if both operands are `true`. |
| 30 | +- `or` provides a logical OR operation. |
| 31 | + - `x or y` evaluates to `true` if either operand is `true`. |
| 32 | +- `not` provides a logical NOT operation. |
| 33 | + - `not x` evaluates to `true` if the operand is `false`. |
| 34 | + |
| 35 | +`and` and `or` are infix binary operators, and use |
| 36 | +[short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation). |
| 37 | +`not` is a prefix unary operator. |
| 38 | + |
| 39 | +## Details |
| 40 | + |
| 41 | +### Precedence |
| 42 | + |
| 43 | +`and` and `or` have very low precedence. When an expression appearing as the |
| 44 | +condition of an `if` uses these operators unparenthesized, they are always the |
| 45 | +lowest precedence operators in that expression. |
| 46 | + |
| 47 | +These operators permit any reasonable operator that might be used to form a |
| 48 | +`bool` value as a subexpression. In particular, comparison operators such as `<` |
| 49 | +and `==` have higher precedence than `and` and `or`. However, the precedence of |
| 50 | +`and` and `or` is not directly comparable with each other, so they cannot both |
| 51 | +be used directly in an expression without parentheses. |
| 52 | + |
| 53 | +`not` is higher precedence than `and` and `or`, but its precedence is |
| 54 | +incomparable with most other operators, including comparison operators. |
| 55 | + |
| 56 | +For example: |
| 57 | + |
| 58 | +```carbon |
| 59 | +// ✅ Valid: `and` is lower precedence than the `<` or `==` operators. |
| 60 | +if (n + m == 3 and not n < m) { |
| 61 | + ... |
| 62 | +} |
| 63 | +// The above is equivalent to: |
| 64 | +if (((n + m) == 3) and (not (n < m))) { |
| 65 | + ... |
| 66 | +} |
| 67 | +
|
| 68 | +// ❌ Invalid: `and` and `or` precedence is incomparable. |
| 69 | +if (cond1 and cond2 or cond3) { |
| 70 | + ... |
| 71 | +} |
| 72 | +// ✅ Valid: Parentheses avoid the precedence check. |
| 73 | +if (cond1 and (cond2 or cond3)) { |
| 74 | + ... |
| 75 | +} |
| 76 | +
|
| 77 | +// ❌ Invalid: `not` precedence is incomparable with `==`. |
| 78 | +if (not cond1 == cond2) { |
| 79 | + ... |
| 80 | +} |
| 81 | +// ❌ Invalid: `not` precedence is incomparable with `==`. |
| 82 | +if (cond1 == not cond2) { |
| 83 | + ... |
| 84 | +} |
| 85 | +// ✅ Valid: Parentheses avoid the precedence check. |
| 86 | +if (cond1 == (not cond2)) { |
| 87 | + ... |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +### Associativity |
| 92 | + |
| 93 | +`and` and `or` are left-associative. A `not` expression cannot be the operand of |
| 94 | +another `not` expression; `not not b` is an error without parentheses. |
| 95 | + |
| 96 | +``` |
| 97 | +// ✅ Valid: `and` is left-associative, and precedence is fine. |
| 98 | +if (not a and not b and not c) { |
| 99 | + ... |
| 100 | +} |
| 101 | +// The above is equivalent to: |
| 102 | +if ((not a) and ((not b) and (not c))) { |
| 103 | + ... |
| 104 | +} |
| 105 | +// ✅ Valid: Parentheses avoid the `not` associativity error. |
| 106 | +if (not (not a)) { |
| 107 | + ... |
| 108 | +} |
| 109 | +
|
| 110 | +// ❌ Invalid: `not not` associativity requires parentheses. |
| 111 | +if (not not a) { |
| 112 | + ... |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +### Conversions |
| 117 | + |
| 118 | +> TODO: This should be addressed through a standard `bool` conversion design. |
| 119 | +
|
| 120 | +The operand of `and`, `or`, or `not` is converted to a `bool` value in the same |
| 121 | +way as the condition of an `if` statement. In particular: |
| 122 | + |
| 123 | +- If we decide that certain values, such as pointers or integers, should not |
| 124 | + be usable as the condition of an `if` without an explicit comparison against |
| 125 | + null or zero, then those values will also not be usable as the operand of |
| 126 | + `and`, `or`, or `not` without an explicit comparison. |
| 127 | +- If an extension point is provided to determine how to branch on the truth of |
| 128 | + a value in an `if` (such as by supplying a conversion to a `bool` type), |
| 129 | + that extension point will also apply to `and`, `or`, and `not`. |
| 130 | + |
| 131 | +### Overloading |
| 132 | + |
| 133 | +The logical operators `and`, `or`, and `not` are not overloadable. As noted |
| 134 | +above, any mechanism that allows types to customize how `if` treats them will |
| 135 | +also customize how `and`, `or`, and `not` treats them. |
| 136 | + |
| 137 | +## Alternatives considered |
| 138 | + |
| 139 | +- [Use punctuation spelling for all three operators](/proposals/p0680.md#use-punctuation-spelling-for-all-three-operators) |
| 140 | +- [Precedence of AND versus OR](/proposals/p0680.md#precedence-of-and-versus-or) |
| 141 | +- [Precedence of NOT](/proposals/p0680.md#precedence-of-not) |
| 142 | +- [Punctuation form of NOT](/proposals/p0680.md#punctuation-form-of-not) |
| 143 | +- [Two forms of NOT](/proposals/p0680.md#two-forms-of-not) |
| 144 | +- [Repeated NOT](/proposals/p0680.md#repeated-not) |
| 145 | +- [AND and OR produce the decisive value](/proposals/p0680.md#and-and-or-produce-the-decisive-value) |
| 146 | + |
| 147 | +## References |
| 148 | + |
| 149 | +- Proposal |
| 150 | + [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680). |
| 151 | +- Proposal |
| 152 | + [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702). |
0 commit comments