How are Q# programs structured?
Before you start writing quantum programs, it's important to understand the structure and components of a Q# program.
In this unit, you'll review the main components of a Q# program.
Note
If you experience problems with the rendering of the formulas, hit the refresh button on your browser. This will reload the page and the formulas will render correctly.
Namespaces
Every Q# file starts with a namespace. Here's an example:
namespace HelloQuantum {
// Your code goes here.
}
The namespace
keyword is used to define a namespace. Namespaces are used to organize Q# code into logical units. Their use becomes important when you use Q# libraries in your programs and when you write your own libraries.
Allocating qubits
In Q#, to obtain a qubit, you use the use
keyword. Every qubit you allocate with the use
keyword starts in the $\ket{0}$ state.
You can allocate one or many qubits at a time. Here's an example that allocates one and five qubits:
use q1 = Qubit(); // Allocate one qubit
use q5 = Qubit[5]; // Allocate five qubits
Quantum operations
Operations are the basic building blocks of a Q# program. A Q# operation is a quantum subroutine. That is, it's a callable routine that contains quantum operations that modify the state of the qubit register.
To define a Q# operation, you specify a name for the operation along with its inputs and its output. Here's a basic example:
operation SayHelloQ() : Unit {
Message("Hello quantum world!");
}
Here, SayHelloQ
is the name of the operation. It takes zero arguments as its input and returns type Unit
, which means that the operation returns no information.
Q# libraries also provide operations that you can use in your programs, such as the Hadamard, H
, operation, which puts a qubit into a superposition state.
Types
Q# provides many built-in types you might be already familiar with, including Int
, Double
, Bool
, and String
.
In this example, the Unit
type is used to indicate that the operation doesn't return any information:
operation SayHelloQ() : Unit {
Message("Hello quantum world!");
}
In the following units, you'll work with the Result
type, which is specific type to quantum computing. A Result
type is the result of measuring a qubit and can be either One
and Zero
.
Quantum libraries
Q# libraries contain functions and operations that you can use in quantum programs. When you call a function or operation from a library, you use the open
directive and specify the library's namespace. For example, to use the Microsoft.Quantum.Intrinsic
library, you do the following:
open Microsoft.Quantum.Intrinsic;
Entry point
EntryPoint
tells the Q# compiler where to begin executing the program. Every Q# program must have one entry point followed by an operation. For example, the following code defines an entry point operation, HelloQ
, that prints "Hello quantum world!" to the console:
namespace HelloQuantum {
open Microsoft.Quantum.Intrinsic;
@EntryPoint()
operation HelloQ() : Unit {
Message("Hello quantum world!");
}
}
Note
Note that the above Q# program opens theMicrosoft.Quantum.Intrinsic
library to use the Message
operation, which writes a message to the console.
Measuring qubits
In Q#, the Measure
operation performs a joint measurement of one or more qubits in the specified Pauli bases, which can be PauliX
, PauliY
, or PauliZ
. The Measure
operation returns a Result
type that is either One
or Zero
.
To implement a measurement in the computational basis $\lbrace\ket{0},\ket{1}\rbrace$ you can also use the M
operation, which performs a measurement in the Pauli Z-basis. Thus, the M
operation is equivalent to applying Measure([PauliZ], [qubit])
.
Resetting qubits
In Q#, qubits must be in the $\ket{0}$ state by the time they are released. When you have finished using a qubit, you use the Reset
operation to reset the qubit to the $\ket{0}$.
// Reset the qubit so it can be safely released.
Reset(qubit);