4 ms·
In golang, X is a subtype of interface{}. But []X isn't a subtype of []interface{} (according to the compiler). Doesn't this violate the above subsitution prin
by toolslive 6y ago
In golang, X is a subtype of interface{}. But []X isn't a subtype of []interface{} (according to the compiler).
Doesn't this violate the above subsitution principle ?
- zozbot234 6y agoIn golang, a white horse is a horse: If you ask me for a horse, I can give you a white horse. But if I want a stable for n horses, it's not correct to give me a stable for n white horses, because that doesn't account for yellow or black horses. Does this violate the substitution principle? (inb4: "It depends on what the meaning of 'is', is!")
- scubbo 6y agoAh, this sounds like co/contravariance - concepts that I have encountered, (re-)learned, and forgotten countless times.
- toolslive 6y agoTo continue your analogy, I want to be able to see the stable of white horses ([]X) as a stable of horses ([]interface{}), since a white horse is a horse after all. In java (or C++ or most other languages), you can do the following String[] strings = {"x0","x1"}; Object[] things = strings; They can't be both right.
- Tyr42 6y agoThat example with arrays only works if you treat the array as immutable. Otherwise you get an exception.
- toolslive 6y agoString[] strings = {"x0","x1"}; strings[0] = "something else"; // mutable. Object[] things = strings; things[1] = null;// mutable. all works.(in java), but I understand what you mean.
- zozbot234 6y agoBut a stable of horses, can accept yellow or black horses. A stable of white horses, cannot accept yellow or black horses. If what one can accept in both cases was the same, it is evident that "white horse" would not differ from "horse". But acceptable and unacceptable horses are mutually contrary. Thus it is clear that a stable of white horses is not a stable of horses.
- toolslive 6y ago> Thus it is clear that a stable of white horses is not a stable of horses. You're not making sense any more.
- nybble41 6y agoA stable that can only contain white horses is not a stable that can contain any kind of horse. Whether you can ignore that distinction depends on whether the stable is in a covariant or contravariant position, i.e. whether you want to get horses from the stable or put horses into the stable. These would be fine: Horse[] genericStable = …; WhiteHorse[] whiteHorseStable = …; genericStable.insert(new WhiteHorse()); Horse someHorse = whiteHorseStable.first(); However, these can fail due to type errors: whiteHorseStable.insert(new BrownHorse()); WhiteHorse horse = genericStable.first(); Because the ability to substitute a subtype for a supertype (or vice-versa) depends on whether the use is covariant or contravariant (or invariant) it becomes difficult to have proper subtype or supertype relationships in object-oriented languages where this distinction is not factored in to the type system. Simplifying a bit, to apply the LSP the language needs to distinguish between getters and setters at the type level and can't treat all methods equally.
- toolslive 6y agoYes! it's about (co|contra)-variance and mutability, and your type system should understand this.
- yongjik 6y agoWait, I'm pretty sure you can't do that in C++ (e.g., you can't cast vector<Base> into vector<Derived> or vice versa), unless you count brute-force C-style cast (which will gladly let you shoot your feet, your coworkers' feet, and everyone's feet).