Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers.
1// Single-line comments start with //
2
3
4/////////////////////////////////////
5// 1. Quantum data types and operators
6
7// The most important part of quantum programs is qubits.
8// In Q# type Qubit represents the qubits which can be used.
9// This will allocate an array of two new qubits as the variable qs.
10operation QuantumDataTypes() : Unit {
11 use qs = Qubit[2];
12
13 // The qubits have internal state that you cannot access to read or modify directly.
14 // You can inspect the current state of your quantum program
15 // if you're running it on a classical simulator.
16 // Note that this will not work on actual quantum hardware!
17 Std.Diagnostics.DumpMachine();
18
19 // If you want to change the state of a qubit
20 // you have to do this by applying quantum gates to the qubit.
21 H(qs[0]); // This changes the state of the first qubit
22 // from |0⟩ (the initial state of allocated qubits)
23 // to (|0⟩ + |1⟩) / sqrt(2).
24 // qs[1] = |1⟩; - this does NOT work, you have to manipulate a qubit by using gates.
25
26 // You can apply multi-qubit gates to several qubits.
27 CNOT(qs[0], qs[1]);
28
29 // You can also apply a controlled version of a gate:
30 // a gate that is applied if all control qubits are in |1⟩ state.
31 // The first argument is an array of control qubits,
32 // the second argument is the target qubit.
33 Controlled Y([qs[0]], qs[1]);
34
35 // If you want to apply an anti-controlled gate
36 // (a gate that is applied if all control qubits are in |0⟩ state),
37 // you can use a library function.
38 ApplyControlledOnInt(0, X, [qs[0]], qs[1]);
39
40 // To read the information from the quantum system, you use measurements.
41 // Measurements return a value of Result data type: Zero or One.
42 // You can print measurement results as a classical value.
43 Message($"Measured {M(qs[0])}, {M(qs[1])}");
44}
45
46
47/////////////////////////////////////
48// 2. Classical data types and operators
49
50function ClassicalDataTypes() : Unit {
51 // Numbers in Q# can be stored in Int, BigInt or Double.
52 let i = 1; // This defines an Int variable i equal to 1
53 let bi = 1L; // This defines a BigInt variable bi equal to 1
54 let d = 1.0; // This defines a Double variable d equal to 1
55
56 // Arithmetic is done as expected, as long as the types are the same
57 let n = 2 * 10; // = 20
58 // Q# does not have implicit type cast,
59 // so to perform arithmetic on values of different types,
60 // you need to cast type explicitly
61 let nd = Std.Convert.IntAsDouble(2) * 1.0; // = 20.0
62
63 // Boolean type is called Bool
64 let trueBool = true;
65 let falseBool = false;
66
67 // Logic operators work as expected
68 let andBool = true and false;
69 let orBool = true or false;
70 let notBool = not false;
71
72 // Strings
73 let str = "Hello World!";
74
75 // Equality is ==
76 let x = 10 == 15; // is false
77
78 // Range is a sequence of integers and can be defined like: start..step..stop
79 let xi = 1..2..7; // Gives the sequence 1,3,5,7
80
81 // Assigning new value to a variable:
82 // by default all Q# variables are immutable;
83 // if the variable was defined using let, you cannot reassign its value.
84
85 // When you want to make a variable mutable, you have to declare it as such,
86 // and use the set word to update value
87 mutable xii = true;
88 set xii = false;
89
90 // You can create an array for any data type like this
91 let xiii = [0.0, size = 10];
92
93 // Getting an element from an array
94 let xiv = xiii[8];
95
96 // Assigning a new value to an array element
97 mutable xv = [0.0, size = 10];
98 set xv w/= 5 <- 1.0;
99}
100
101
102/////////////////////////////////////
103// 3. Control flow
104
105operation ControlFlow() : Unit {
106 let a = 1;
107 // If expressions support a true branch, elif, and else.
108 if (a == 1) {
109 // ...
110 } elif (a == 2) {
111 // ...
112 } else {
113 // ...
114 }
115 use qubits = Qubit[2];
116
117 // For loops can be used to iterate over an array
118 for qubit in qubits {
119 X(qubit);
120 }
121
122 // Regular for loops can be used to iterate over a range of numbers
123 for index in 0..Length(qubits) - 1 {
124 X(qubits[index]);
125 }
126
127 // While loops are restricted for use in classical context only
128 mutable index = 0;
129 while (index < 10) {
130 set index += 1;
131 }
132
133 let success_criteria = true;
134 // Quantum equivalent of a while loop is a repeat-until-success loop.
135 // Because of the probabilistic nature of quantum computing sometimes
136 // you want to repeat a certain sequence of operations
137 // until a specific condition is achieved; you can use this loop to express this.
138 repeat {
139 // Your operation here
140 } until (success_criteria) // This could be a measurement to check if the state is reached
141 fixup {
142 // Resetting to the initial conditions, if required
143 }
144}
145
146/////////////////////////////////////
147// 4. Putting it all together
148
149// Q# code is written in operations and functions
150operation ApplyXGate(source : Qubit) : Unit {
151 X(source);
152}
153
154// If the operation implements a unitary transformation, you can define
155// adjoint and controlled variants of it.
156// The easiest way to do that is to add "is Adj + Ctl" after Unit.
157// This will tell the compiler to generate the variants automatically.
158operation ApplyXGateCA(source : Qubit) : Unit is Adj + Ctl {
159 X(source);
160}
161
162// Now you can call Adjoint ApplyXGateCA and Controlled ApplyXGateCA.
163
164
165// To run Q# code, you can put @EntryPoint() before the operation you want to run first
166operation XGateDemo() : Unit {
167 use q = Qubit();
168 ApplyXGate(q);
169}
170
171// Here is a simple example: a quantum random number generator.
172// We will generate a classical array of random bits using quantum code.
173// Callables (functions or operations) named `Main` are used as entry points.
174operation Main() : Unit {
175 mutable bits = [0, size = 5]; // Array we'll use to store bits
176 use q = Qubit();
177 {
178 // Allocate a qubit
179 for i in 0..4 {
180 // Generate each bit independently
181 H(q); // Hadamard gate sets equal superposition
182 let result = M(q); // Measure qubit gets 0|1 with 50/50 prob
183 let bit = result == Zero ? 0 | 1; // Convert measurement result to integer
184 set bits w/= i <- bit; // Write generated bit to an array
185 }
186 }
187 Message($"{bits}"); // Print the result
188}
Further Reading ¶
The Quantum Katas (repo hosted tutorials offer great self-paced tutorials and programming exercises to learn quantum computing and Q#.
Q# Documentation is official Q# documentation, including language reference and user guides.