# Precedence and associativity

Precedence and associativity define the order in which operators are applied. Operators with higher precedence are bound to their arguments (operands) first, while operators with the same precedence bind in the direction of their associativity.
For example, the expression `1+2*3`

according to the precedence for addition and multiplication is equivalent to `1+(2*3)`

, and `2^3^4`

equals `2^(3^4)`

since exponentiation is right-associative.

## Operators

The following table lists the available operators in Q#, as well as their precedence and associativity. Additional modifiers and combinators are also listed, and bind tighter than any of these operators.

Description | Syntax | Operator | Associativity | Precedence |
---|---|---|---|---|

copy-and-update operator | `w/` `<-` |
ternary | left | 1 |

range operator | `..` |
infix | left | 2 |

conditional operator | `? \|` |
ternary | right | 3 |

logical OR | `or` |
infix | left | 4 |

logical AND | `and` |
infix | left | 5 |

bitwise OR | `\|\|\|` |
infix | left | 6 |

bitwise XOR | `^^^` |
infix | left | 7 |

bitwise AND | `&&&` |
infix | left | 8 |

equality | `==` |
infix | left | 9 |

inequality | `!=` |
infix | left | 9 |

less-than-or-equal | `<=` |
infix | left | 10 |

less-than | `<` |
infix | left | 11 |

greater-than-or-equal | `>=` |
infix | left | 11 |

greater-than | `>` |
infix | left | 11 |

right shift | `>>>` |
infix | left | 12 |

left shift | `<<<` |
infix | left | 12 |

addition or concatenation | `+` |
infix | left | 13 |

subtraction | `-` |
infix | left | 13 |

multiplication | `*` |
infix | left | 14 |

division | `/` |
infix | left | 14 |

modulus | `%` |
infix | left | 14 |

exponentiation | `^` |
infix | right | 15 |

bitwise NOT | `~~~` |
prefix | right | 16 |

logical NOT | `not` |
prefix | right | 16 |

negative | `-` |
prefix | right | 16 |

Copy-and-update expressions necessarily need to have the lowest precedence to ensure a consistent behavior of the corresponding evaluate-and-reassign statement. Similar considerations hold for the range operator to ensure a consistent behavior of the corresponding contextual expression.

## Modifiers and combinators

Modifiers can be seen as special operators that can be applied to certain expressions only. They can be assigned an artificial precedence to capture their behavior.

For more information, see Expressions.

This artificial precedence is listed in the following table, along with how the precedence of operators and modifiers relates to how tightly item access combinators (`[`

,`]`

and `::`

respectively) and call combinators (`(`

, `)`

) bind.

Description | Syntax | Operator | Associativity | Precedence |
---|---|---|---|---|

Call combinator | `(` `)` |
n/a | left | 17 |

Adjoint functor | `Adjoint` |
prefix | right | 18 |

Controlled functor | `Controlled` |
prefix | right | 18 |

Unwrap application | `!` |
postfix | left | 19 |

Named item access | `::` |
n/a | left | 20 |

Array item access | `[` `]` |
n/a | left | 20 |

Function lambda | `->` |
n/a | right | 21 |

Operation lambda | `=>` |
n/a | right | 21 |

To illustrate the implications of the assigned precedences, suppose you have a unitary operation `DoNothing`

(as defined in Specialization declarations), a callable `GetStatePrep`

that returns a unitary operation, and an array `algorithms`

that contains items of type `Algorithm`

defined as follows

```
newtype Algorithm = (
Register : Qubit[],
Initialize : Transformation,
Apply : Transformation
);
newtype Transformation =
Qubit[] => Unit is Adj + Ctl;
```

The following expressions, then, are all valid:

```
GetStatePrep()(arg)
(Transformation(GetStatePrep()))!(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0]::Apply!(cs, _)
algorithms[0]::Register![i]
```

Looking at the precedences defined in the table above, you can see that the parentheses around `(Transformation(GetStatePrep()))`

are necessary for the subsequent unwrap operator to be applied to the `Transformation`

value rather than the returned operation.
However, parentheses are not required in `GetStatePrep()(arg)`

; functions are applied left-to-right, so this expression is equivalent to `(GetStatePrep())(arg)`

.
Functor applications also don't require parentheses around them in order to invoke the corresponding specialization, nor do array or named item access expressions. Thus, the expression `arr2D[i][j]`

is perfectly valid, as is `algorithms[0]::Register![i]`

.

## Feedback

https://aka.ms/ContentUserFeedback.

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for