Repository: quantumlib/Cirq

Issue:
Rename `cirq.channel` to `cirq.kraus`?
**Is your design idea/issue related to a use case or problem? Please describe.**

In QIS literature "channel" or "quantum channel" refers to a CPTP map from the space of linear operators on a Hilbert space H1 to the space of linear operators on a Hilbert space H2. This is fairly abstract and people have formulated more concrete representations of channels such as the Kraus representations, the Choi representation etc.

Adding a utility to compute the Choi matrix of a channel (#4132) made me realize that we have a protocol `cirq.channel` which returns Kraus operators of a channel. This is a little unfortunate as it conflates the abstract concept ("channel") with one of many of its concrete representations ("Kraus representation").

**Describe your design idea/issue**

Suggestion: rename `cirq.channel` to `cirq.kraus`. This would fit nicely with `cirq.choi` and potentially other channel representations in future (e.g. `cirq.stinespring`).



Discussion:
@dabacon @daxfohl @maffoo @mpharrigan 

Related: #3248.
If we do something like this, I think this would be a good opportunity for the protocol to return a thin wrapper class `Kraus`, which would have nice `to_choi` etc methods, any other things that make sense to Kraus representation, (along with `get_raw_data(copy=False)` method). Getting fancy, `Kraus` could implement a `Channel` interface that perhaps contains declarations of `to_choi`, `to_kraus`, etc.
`cirq.kraus` sounds good to me. I'll usually push back against wrapper classes unless we go whole hog with `cirq.unitary` `cirq.final_state_vector`, et al. Even then I think there's something to be said for numpy arrays.
While we're at it, we could also rename the internal method `__channel__` that channel classes use to provide their Kraus representation (to `__kraus__`). In future some channels might choose to specify their action via other means, e.g. `__choi__`. Even if this does not happen, `__kraus__` is more suggestive of what it should return than `__channel__`.
Accepted at weekly meeting. @maffoo and @95-martin-orion pointed out that we'll soon have `cirq.Channel` class, so this renaming is in fact fairly urgent to avoid name conflict between the new type name and the protocol for getting a Kraus representation.
@mpharrigan agree with your sentiment. It's just that now seems like the best opportunity to start with a channel class hierarchy if we ever want to have one. Once this gets created it'll be hard to revisit that decision. So there should at least be a discussion. 
Also, perhaps a loaded question, but why does this have to be a protocol? My knee jerk reaction was always that this would be more natural as an interface or mixin, so that `.kraus` would be exposed directly on classes that supported it. Maybe I'm too used to Java. 
In object-oriented programming you get type polymorphism at the cost of having to construct a taxonomy for your classes and then having to comply with that taxonomy by ensuring inheritance relationships that yield the desired dispatch behavior.

By contrast, protocols allow you to form subtype relationships *implicitly*. Instead of explicitly saying that one type inherits from another, you decide on some conditions that a type has to satisfy for the protocol to work on it. For example, you can decide that anything you can open, read from and close qualifies to be a file. Or that anything that provides a unitary, a Choi matrix or a collection of Kraus operators qualifies to be a quantum channel. Once a type fulfills these *structural* conditions then anyone can use it with the protocol.

\<opinion\>The more implicit approach offered by protocols is generally considered more pythonic.\</opinion\>

See [PEP 544](https://www.python.org/dev/peps/pep-0544/) for details.
Super quick RFC on the channel type mentioned above: https://tinyurl.com/cirq-custom-channel

Resolving patch:
diff --git a/cirq-core/cirq/protocols/__init__.py b/cirq-core/cirq/protocols/__init__.py
--- a/cirq-core/cirq/protocols/__init__.py
+++ b/cirq-core/cirq/protocols/__init__.py
@@ -38,7 +38,7 @@
     approx_eq,
     SupportsApproximateEquality,
 )
-from cirq.protocols.channel import (
+from cirq.protocols.kraus import (
     channel,
     kraus,
     has_channel,
diff --git a/cirq-core/cirq/protocols/apply_channel_protocol.py b/cirq-core/cirq/protocols/apply_channel_protocol.py
--- a/cirq-core/cirq/protocols/apply_channel_protocol.py
+++ b/cirq-core/cirq/protocols/apply_channel_protocol.py
@@ -24,7 +24,7 @@
     apply_unitary,
     ApplyUnitaryArgs,
 )
-from cirq.protocols.channel import kraus
+from cirq.protocols.kraus import kraus
 from cirq.protocols import qid_shape_protocol
 from cirq.type_workarounds import NotImplementedType
 
diff --git a/cirq-core/cirq/protocols/channel.py b/cirq-core/cirq/protocols/kraus.py
similarity index 100%
rename from cirq-core/cirq/protocols/channel.py
rename to cirq-core/cirq/protocols/kraus.py


Test patch:
diff --git a/cirq-core/cirq/protocols/channel_test.py b/cirq-core/cirq/protocols/kraus_test.py
similarity index 99%
rename from cirq-core/cirq/protocols/channel_test.py
rename to cirq-core/cirq/protocols/kraus_test.py
--- a/cirq-core/cirq/protocols/channel_test.py
+++ b/cirq-core/cirq/protocols/kraus_test.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Tests for channel.py."""
+"""Tests for kraus.py."""
 
 from typing import Iterable, Sequence, Tuple