Conditional branching

Conditional branching is expressed in the form of if expressions. An if expression consists of an if clause, followed by zero or more elif clauses and optionally an else-block. Each clause follows the pattern

keyword condition {
    <statements>
}

where keyword is replaced with if or elif respectively, condition is an expression of type Bool, and <statements> is to be replaced with zero or more statements. The optional else-block consists of the keyword else followed by zero or more statements enclosed in braces, { }.

The first block for which the condition evaluates to true will run. The else block, if present, runs if none of the conditions evaluate to true. The block is executed in its own scope, meaning any bindings made as part of the block are not visible after the block ends.

For example, suppose qubits is value of type Qubit[] and r1 and r2 are of type Result,

if r1 == One {
    let q = qubits[0];
    H(q);
} 
elif r2 == One {
    let q = qubits[1];
    H(q);
} 
else {
    H(qubits[2]);
}

You can also express simple branching in the form of a conditional expression.

Target-specific restrictions

The tight integration between control-flow constructs and quantum computations poses a challenge for current quantum hardware. Certain quantum processors do not support branching based on measurement outcomes. As such, comparison for values of type Result will always result in a compilation error for Q# programs that are targeted to run on such hardware.

Other quantum processors support specific kinds of branching based on measurement outcomes. The more general if expressions supported in Q# are compiled into suitable instructions that can be run on such processors. The imposed restrictions are that values of type Result may only be compared as part of the condition within if expressions in operations. Furthermore, the conditionally run blocks cannot contain any return expressions or update mutable variables that are declared outside that block.