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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions