Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Add the concept of an rvalue #131

@Strilanc

Description

@Strilanc

One of the major pains of working with Q# is that a lot of slight variations on operations require special casing. For example, suppose I want to swap two registers if two LittleEndian registers are equal, and I have already written methods to prepare the equality result and do a swap conditioned on a control. Further assume I am trying to be efficient and want to avoid redundant recomputation of ancillae when uncomputation the equality result. Then I am basically forced to write this:

use control_holder = Qubit();
use temporary_ancillae = Qubit[n];
within {
    init_equality_result(a, b, temporary_ancillae, control_holder);
} apply {
    Controlled swap_registers([control_holder], (c, d))
}

What I would like to write instead is this:

if a == b {
    swap(c, d);
}

but that's perhaps a bit ambitious so in this issue I will settle for suggesting this:

Controlled swap_registers([temporary_equals_result(a, b)], (c, d));

The intention here is that temporary_equals_result returns some kind of special type, called something like QubitExpression or QuantumRValue, which defines methods for initializing and uncomputing a result with automatically managed auxilliary storage. The idea is that these explicitly specified methods are explaining things like "there will be n ancillae whose lifetimes is tied to the lifetime of the result" and "you can use measurement based uncomputation when getting rid of the ancillae".

Anyways, I'm sure this needs a lot of refinement, but the inability to plug temporary expressions together and have the compiler automatically make sure they appear and disappear as needed in a LIFO ordering does strike me as one of the major reasons that writing Q# code produces a lot of boilerplate (and feels like such a slog) compared to writing expressions in other languages.

I did actually mock out this idea in https://github.com/Strilanc/quantumpseudocode and it seemed to work well. But it was severely hampered by that library's inability to automatically derive inverses, which is not a problem in Q#.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions