QuantumScript (.qts)
QuantumScript is a strict, TypeScript-inspired, natively compiled programming language designed to bridge classical web development and quantum computing. It allows developers to model quantum superposition, entanglement, and wave-function collapse using high-level syntax that runs locally via a Go binary, or directly inside web applications via a client-side WebAssembly (WASM) runner.
Key Language Features
Strict Type Checking
The compiler enforces distinct boundaries between classical variables (number, string, boolean) and quantum registers (qubit). Attempting to use classical values inside quantum gates throws immediate syntax errors.
Quantum Garbage Collection
Underneath, the language engine tracks local qubits and automatically uncomputes their history using conjugate transpose adjoint gates when they leave scope, preventing state leakage.
Implicit Entanglement
Placing qubit registers inside conditional if blocks automatically converts the statements into multi-controlled quantum operations (like Controlled-NOT gates).
Hardware SWAP Routing
Compiles directly into OpenQASM 3.0 for actual hardware, automatically generating SWAP gates to map qubits onto linear chip topologies.
Installation & CLI
QuantumScript is built in Go, offering a fast compiler and local simulator engine. You can run quantum algorithms locally using the terminal or embed the WebAssembly bundle in your frontend application.
Local Installation (Windows)
Run the automated installer script from the root of the cloned repository to build and expose the qs CLI tool globally:
.\install.ps1
Using the CLI Compiler
The compiler exposes several subcommands to build and run files ending in .qts or .qs:
1. Scaffold a New Project
qs init my-quantum-project
This creates a new folder containing main.qts and module.qts showcasing modular imports and exports.
2. Run Simulator (1,000 Shots)
qs run main.qts
The engine executes the code 1,000 times, recording statistics on the measured qubits and displaying the probability of collapsing into the state \(|1\rangle\) or \(|0\rangle\).
3. Hardware Noise Simulation
Simulate realistic hardware imperfections by injecting a depolarizing error rate. A noise value of 0.05 adds a 5% chance of a random Pauli error (\(X\), \(Y\), or \(Z\)) after every gate application:
qs run --noise=0.05 main.qts
4. Export to IBM QASM 3.0
qs export-qasm main.qts
Generates OpenQASM 3.0 code ready to be executed on physical IBM quantum computers.
VS Code Extension & LSP
QuantumScript includes a dedicated Language Server Protocol (LSP) server for real-time syntax checking, auto-completions, and type warnings.
To start the server manually:
qs lsp
To enable syntax highlighting and editor errors, install the included VS Code extension located in vscode-extension/ in this repository.
Classical Logic & Math
QuantumScript provides standard classical data types and mathematical structures so you can build classical control loops that prepare or process quantum states.
Declaring Variables
Variables are declared using block-scoped const (read-only) or let (mutable) keywords, matching TypeScript syntax:
const pi: number = 3.14159265;
let iterations: number = 10;
const label: string = "Entanglement Run";
const isVerified: boolean = true;
Object Literals
Structure complex data structures using inline object literals:
const config: object = {
shots: 1000,
noiseModel: "depolarizing",
verbose: false
};
const shotCount: number = config.shots;
Built-in Math Module
The compiler integrates a native Math module containing fundamental mathematical operations and constants (e.g. for rotation gate angles):
| Expression | Return Type | Description |
|---|---|---|
Math.PI or Math.pi |
number |
The circle ratio constant \(\pi \approx 3.14159\) |
Math.sin(theta) |
number |
Trigonometric Sine function |
Math.cos(theta) |
number |
Trigonometric Cosine function |
Math.sqrt(val) |
number |
Square root function |
Qubits & Quantum Gates
QuantumScript treats the qubit as a native, compiler-tracked reference. Qubits are allocated in the absolute zero state \(|0\rangle\) and manipulated using a set of built-in gate operations.
Qubit Allocation
Instantiate a qubit by invoking the Qubit constructor with the new keyword:
const q: qubit = new Qubit(); // Allocated in state |0⟩
Core Quantum Operations
QuantumScript exposes three core primitives built into the syntax:
1. Superposition: superpose(q)
Applies a Hadamard (H) gate to the qubit, shifting it into a 50/50 superposition of \(|0\rangle\) and \(|1\rangle\):
\[H |0\rangle = \frac{|0\rangle + |1\rangle}{\sqrt{2}}\]2. Inversion: invert(q)
Applies a Pauli-X (Not) gate. Flips a qubit from \(|0\rangle \to |1\rangle\) or vice-versa.
3. Collapse: measure(q)
Collapses the quantum state vector, returning a classical boolean. If the state collapses to \(|1\rangle\), it returns true. If it collapses to \(|0\rangle\), it returns false.
Standard Gate Library
For fine-tuned algorithms, the following mathematical gates are exposed in the compiler namespace:
- Pauli Gates:
X(q),Y(q),Z(q) - Phase Gates:
S(q)(90-degree Z rotation),T(q)(45-degree Z rotation) - Rotational Gates:
Rx(theta, q),Ry(theta, q),Rz(theta, q)
// Rotate a qubit into a half-angle state using Ry
const q: qubit = new Qubit();
Ry(Math.PI / 4, q);
The Adjoint Modifier
You can execute the mathematical inverse (complex conjugate transpose) of any standard operation by prefixing the function call with the adjoint keyword. This is heavily used to reverse operations during uncomputation:
adjoint S(q); // Becomes S-dagger (Sdg)
adjoint Rx(Math.PI, q); // Becomes Rx(-Math.PI)
Arbitrary State Preparation
The compiler provides a utility function StatePrep(amplitudes: number[], register: qubit[]) to initialize qubits directly into specific state vector configurations. The simulator automatically normalizes the array amplitude vector:
const reg: qubit[] = new Qubit[2];
// Prepares state: 0.6|00⟩ + 0.8|11⟩
StatePrep([0.6, 0.0, 0.0, 0.8], reg);
Loops, Functions & Garbage Collection
QuantumScript allows you to scale algorithms by combining arrays, loops, modular functions, and automatic quantum uncomputation.
Qubit Registers (Arrays)
Allocate a register containing multiple qubits using array syntax:
const register: qubit[] = new Qubit[5]; // Allocate 5 qubits
You can iterate over the register using classical for or while loops:
// Put the entire register into uniform superposition
for (let i = 0; i < 5; i = i + 1) {
superpose(register[i]);
}
Custom Quantum Functions
Write reusable quantum routines by declaring functions with parameters and return types:
function initializeBellState(c: qubit, t: qubit) {
superpose(c);
if (c) {
invert(t);
}
}
Automatic Quantum Garbage Collection
When running quantum algorithms, temporary workspace qubits (called ancilla qubits) are often required inside a function block. If these qubits are discarded without returning them to their initial state, they remain entangled with the system. This phenomenon creates **quantum phase noise**, destroying the coherence of the overall algorithm.
QuantumScript solves this automatically at the language level. When a qubit goes out of scope (e.g., at the end of a block or function execution), the compiler:
- Traces the entire operations history applied specifically to that qubit in the current scope.
- Iterates backward through the history list.
- Applies the mathematical
adjointof each gate. - Successfully returns the qubit back to the state \(|0\rangle\), clean of entanglement, before reclaiming the memory index.
Entanglement (Control Context)
In classical programming, an if statement branches execution based on a boolean condition. In QuantumScript, passing a qubit into an if condition shifts the compilation context into a **Quantum Control Block**.
Syntax and Operation
When a qubit condition is evaluated, any quantum gate applied within the branch is conditioned on the state of that controller qubit. This allows you to construct entanglement without needing a separate library of CX, CY, or CZ gates:
const ctrl: qubit = new Qubit();
const target: qubit = new Qubit();
superpose(ctrl); // Shifts control into |0⟩ + |1⟩
// Implicit Controlled Operation (acting as a CNOT)
if (ctrl) {
invert(target);
}
Because the condition is a qubit in superposition, the gates inside the branch execute *partially* based on the quantum amplitude of the controller. This couples the state vectors of the two qubits, generating **quantum entanglement**.
Multi-Qubit Control
Nesting control blocks increases the control requirements. Nesting two conditions creates a Controlled-Controlled-NOT (Toffoli) equivalent:
const c1: qubit = new Qubit();
const c2: qubit = new Qubit();
const target: qubit = new Qubit();
if (c1) {
if (c2) {
invert(target); // Executes as a Toffoli gate
}
}
if block conditioned on a qubit). Doing so will trigger a compilation error because a quantum computer cannot branch classical values.
QASM Transpilation & Routing
QuantumScript is built to execute algorithms. In addition to simulating states locally, the compiler includes a transpiler to prepare circuits for physical hardware.
OpenQASM 3.0 Export
OpenQASM is the industry standard assembly language for quantum devices. To export a script into a clean, flat QASM representation, run the export CLI tool:
qs export-qasm main.qts
This writes a main.qts.qasm file declaring the register mappings and physical gate instructions.
Linear Topology SWAP Routing
On physical quantum chips, qubits are wired together on a grid or grid-like lattice (e.g. heavy-hex or linear chains). Two-qubit operations (like Controlled-Not) can only be executed between qubits that are physically adjacent on the chip.
If your code applies a controlled operation between q0 and q3 on a linear topology machine, the compiler must route the quantum information. By setting the topology flag, the QuantumScript compiler automatically routes the states using SWAP operations:
qs export-qasm --topology=linear main.qts
Routing Process Example
To control q3 with q0, the compiler automatically generates the following OpenQASM sequence:
swap q0[0], q1[0];(Moves state 0 next to 1)swap q1[0], q2[0];(Moves state 0 next to 2, adjacent to 3)cx q2[0], q3[0];(Applies the physical controlled operation)swap q1[0], q2[0];(Reverts state 0 back)swap q0[0], q1[0];(Returns system to initial layout)
This automated routing makes writing complex algorithms independent of specific hardware layouts.
Interactive Playground
Write, edit, and simulate QuantumScript code in real time using the built-in Go WebAssembly compiler runtime. Choose an example to get started, adjust the noise level slider, and hit **Run Algorithm**.