Upcoming features¶
Guppy Algorithms is under active development. This page describes planned directions rather than APIs that users should rely on today.
Unified control and dagger modifiers¶
Guppy’s built-in control and dagger modifiers already work well for simple,
straight-line unitary functions. Mark the function as unitary so Guppy checks
that it can be both controlled and inverted:
from guppylang import guppy
from guppylang.std.builtins import control, dagger
from guppylang.std.quantum import h, qubit, s
@guppy(unitary=True)
def basis_change(target: qubit) -> None:
h(target)
s(target)
@guppy
def use_modifiers(control_qubit: qubit, target: qubit) -> None:
with control(control_qubit):
basis_change(target)
with dagger:
basis_change(target)
controladdscontrol_qubitas a control to the quantum operations inbasis_change.daggerreverses the operation order and replaces each gate with its adjoint.unitary=Truedeclares both capabilities, and Guppy verifies the function body when it is defined.
The current modifier constraints do not cover every construction in this repository:
A
daggerblock cannot contain loops or branches.Allocation, measurement, reset, and discard cannot appear inside
controlordagger.Functions called under
daggermust explicitly declare the required capability.Several algorithms therefore provide separate controlled, compute, or uncompute implementations. The approach is correct, but it is not yet uniform across the library.
We are waiting for custom-modifier support in Guppy before standardizing this across Guppy Algorithms. The intended direction is to:
define control and adjoint transformations through one modifier framework;
let higher-order functions and structs request those capabilities through their types;
reuse the same primitive in ordinary, controlled, and adjoint contexts where its implementation permits; and
retain explicit specialized implementations where measurement-based uncomputation or another non-unitary technique requires them.
Until that support is available, use the controlled and inverse variants
documented by each component rather than assuming that every library function
can be placed inside control or dagger.