Why mutable and immutable types can never be subtypes of each other
Why isn't mutable a subtype of immutable, or vice versa?
A common question in programming language forums: why aren't mutable and immutable variants of a data structure subtypes of one another? The answer lies in Liskov's substitution principle, which requires that a subtype be usable in every context where its supertype is expected. An immutable pair lacks mutating operations, so it can't substitute for a mutable pair. Conversely, a mutable pair can't substitute for an immutable pair because it doesn't guarantee the contract that repeated reads return the same value—a contract essential for hash consing. Thus they must be separate types. Ad hoc polymorphism (type classes, interfaces, duck typing) can provide shared read operations without a subtype hierarchy.
Because of this, immutable and mutable pairs have to be completely different types.
- zkmon
The fact that it requires so much explanation, indicates the level of degradation in the reasoning ability of the audience. A value of a subtype shall deliver all of the expectations of its super type, because it is wearing both the hats of super type and sub type.
- raincole
In other words, immutable != read only.
In C# ReadOnlyCollection<T> and ImmutableArray<T> are two completely different things for this exact reason.
- gus_massa
Yep, I wondered that for a few optimizations in Racket. It's harder than it looks, probably something about covariant or contravariant types, I gave up.