Skip to content

Replace "structure" protocols with regular properties #7469

@daxfohl

Description

@daxfohl

Is your design idea/issue related to a use case or problem? Please explain

Mathematical protocols like unitary and channel, and relational protocols like commutes and act_on all provide useful flexibility in implementation and allow for nice characteristics like fallback options and multiple dispatch. But protocols that return structural attributes, in particular measurement_keys and control_keys, and to a lesser extent qid_shape and num_qubits, have always seemed to be a bit of a stretch. They add a fair amount of overhead both in terms of boilerplate required and performance, without providing much benefit compared to other protocols. They're also harder for end users to work with because they have to be fished out of the global cirq (or protocols) namespace; cirq.measurement_keys(op) rather than op.measurement_keys, running counter to the "principle of least surprise". Additionally, some of them are also available as properties on some classes, which can lead to confusion as to why there are two ways to get the same info.

Describe your design idea/issue

Add the corresponding methods/properties to Operation, either abstract or virtual with default implementation (some are already there), and deprecate the protocols. Some care would be needed to ensure backwards compatibility for third-party Operations (so probably no "abstract" until cirq 2.0), but it should be doable.

The one counterpoint I can think of is that in the commutes protocol, it uses the measurement_keys and control_keys protocols to check if two operations have overlapping keys. That check would have to change to an if isinstance(x, Operation) and isinstanc(y, Operation) and then check the properties of the operations. From a purity perspective, it'd be nice if protocols could rely solely on other protocols rather than isinstance. But even Python magic methods themselves have such workarounds, like len calls directly into the CPython code for built-in types, rather than relying on __len__. So I think we can use the same rationale, that cirq's commutes handles cirq's built-in Operation explicitly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions