I am having difficulty understanding of subtrait and supertrait relationships in Rust. I think the idea of subtrait and supertrait comes from the set theory, so in set theory, they are known as subset and superset respectively.
For example A = {1, 2, 3, 4} and B = { 1, 2, 3}. B is the subset of the A, and A is the superset of the B.
Now let's say I have two traits Tn and TnMut. Tn has a method named read_show and TnMut has two methods: read_show, and mutate.
I can write them as the following: Tn = { read_show } and TnMut = { read_show, mutate }.
From this we can clearly see that Tn is the subset or subtrait of the TnMut, and TnMut is the superset or supertrait of the Tn.
Here is how I am trying to declare these two traits:
The line TnMut:Tn is considered as subtrait : supertrait ; I understand this line as TnMut is the subtrait of Tn, and Tn is the supertrait of the TnMut. But that seems incorrect if we compare it to set theory. The correct version which follows the set theory is Tn is the subtrait of the TnMut and TnMut is the supertrait of Tn.
If I consider TnMut : Tn as supertrait : subtrait then it makes sense: Tn is the subtrait of the TnMut and TnMut is the supertrait of Tn. However in the Rust tutorial this supertrait : subtrait interpretation seems incorrect.
Could someone please help me understand this issue in simple English?
Thanks.
Non-mathematical: A sub-trait will have all the methods of the super-trait, plus its own (along with associated types, but we can ignore them now for sake of simplicity). That's all there is to it - if you have trait A: B, then when you implement A on a type, you also must implement B.
Mathematical: A sub-trait is called "sub" in-terms of the set of all implementors. Consider trait A: B. Let I_A be the set of all types implementing A and I_B be the corresponding for B. You can see that I_A must be a subset of I_B since any type that implements A must implement B but converse is not true.
Given those trait definitions, you can make structs that implement Tn And ones that implement Tn and TnMut but not TnMut alone.
So, if we consider all the possible implementations of the supertrait Tn, some subset of them would implement TnMut as well, but some of them wouldn’t.
Relating this to your example sets, traits are like conditions that numbers may fulfill. A is the set of positive integers less than 5. B is the set of positive integers less than 4. We can call “being a positive integer less than 5” a “super-condition” of the condition of “being a positive integer less than 4” since if you are less than 4 you are less than five but not the other way around. So we can define B as a subset of A using the “subcondition” of “being a positive integer less than 4”
Let subset A = { methods in TnMut } and superset B = { methods in Tn }, then, according to the wiki quote, we get the sentence via replacing the elements with methods:
The set of methods in TnMut is a subset of the set of methods in Tn if all methods in TnMut are also methods in Tn.
That's to say: Methods in Tn (superset) contains methods in TnMut (subset) and maybe much more.
They are obviously wrong because Tn doesn't have the mutate method.
Oh, we get the wrong definition
Let subset A = { types with TnMut } and superset B = { types with Tn }, then, according to the wiki quote, we get the sentence via replacing elements with types:
The set of types with TnMut is a subset of the set of types with Tn if all the types with TnMut are also types with Tn.
That's to say: Types with Tn (superset) contains types with TnMut (subset) and maybe much more.
Then we get the correct definition