I feel like the explanation is overcomplicated. Types are properties of values, not variables. Mutability is a property of variable, not of a value.
So it's kind of a categorical error. When we speak of "type of a variable", we mean this variable can only be assigned (bound to) values of certain type. This has nothing to do with whether it can be reassigned (i.e. mutability).
So you don't even need the notion of subtyping to explain this.
Also, one could probably define variable as a monad over its type.
BlackFly [3 hidden]5 mins ago
If you pair mutability with exclusive access then you have handled the objection raised by the (some may say overly) strict definition of subtyping here and also the attempt to argue over the objection. No code which asks for an immutable instance will ever observe the mutability because the ask for an immutable reference is exclusive. Therefore, you could pass the mutable reference but so long as something holds onto that reference the mutability is no longer available to other code.
So mutability xor aliasing provides this strict subtyping relation. Of course, you also then need ways of loosening this by providing objects without such a contract and you enter the land of interior mutability, where again the mutable methods can be understood as a part of a subtype because a holder of the reference without mutable methods was explicitly told that there was no the guarantee that the object wouldn't change.
raincole [3 hidden]5 mins ago
In other words, immutable != read only.
In C# ReadOnlyCollection<T> and ImmutableArray<T> are two completely different things for this exact reason.
cubefox [3 hidden]5 mins ago
I would phrase it in terms of subsets. All cats are mammals, therefore "cat" is a subtype of "mammal". So the possible values of the type "cat" are a subset of the possible values of the type "mammal".
In contrast, neither are the mutable things a subset of the immutable things nor the other way round. It's not the case that everything mutable is immutable nor that everything immutable is mutable. The two types are disjoint.
comrade1234 [3 hidden]5 mins ago
Isn't NSMutableArray a subclass of NSArray in a few languages?
bartvk [3 hidden]5 mins ago
Good one, yes. It was like that in Objective-C, and in the early versions of Swift. I know you know this, but it's useful to summarize for myself:
Basically inheritance is the wrong tool for this kind of stuff. NSMutableArray inherits from NSArray, so it can be passed to anywhere NSArray is expected (upcasting).
So you design your classes and expect them to be immutable, but you can't use NSArray anywhere. Because otherwise, it'll be mutable after all. You can do a runtime check as a workaround.
(I truly believe OOP should only be taught in computer science as a relic).
nicky0 [3 hidden]5 mins ago
"Was" like that? .... Some of us still use Objective-C!
catoc [3 hidden]5 mins ago
Yes, that’s ObjC, any NSMutableArray is an NSArray (and an NSObject) - classes passed by reference.
Swift is completely different. Standard arrays are structures, always mutable - value types passed by value
gus_massa [3 hidden]5 mins ago
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.
zkmon [3 hidden]5 mins ago
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.
Shorel [3 hidden]5 mins ago
Not all all. It merely indicates that this is an strict logic approach to the topic.
What part of GP's one-sentence explanation is not strictly logical? Does obfuscating a simple logical concept by describing it in academia-wanky-terms like Liskov's Substitution Principle make it More Logical? Or does it just make the author and their in-crowd feel more intelligent?
Note, also, that the article isn't even objective. It asserts that the definition of a subtype is Liskov's principle. However, Liskov's principle is only one of multiple possible definitions. In other words, the article is really only invoking Liskov's name as an appeal to authority. So much for strict logic.
So it's kind of a categorical error. When we speak of "type of a variable", we mean this variable can only be assigned (bound to) values of certain type. This has nothing to do with whether it can be reassigned (i.e. mutability).
So you don't even need the notion of subtyping to explain this.
Also, one could probably define variable as a monad over its type.
So mutability xor aliasing provides this strict subtyping relation. Of course, you also then need ways of loosening this by providing objects without such a contract and you enter the land of interior mutability, where again the mutable methods can be understood as a part of a subtype because a holder of the reference without mutable methods was explicitly told that there was no the guarantee that the object wouldn't change.
In C# ReadOnlyCollection<T> and ImmutableArray<T> are two completely different things for this exact reason.
In contrast, neither are the mutable things a subset of the immutable things nor the other way round. It's not the case that everything mutable is immutable nor that everything immutable is mutable. The two types are disjoint.
Basically inheritance is the wrong tool for this kind of stuff. NSMutableArray inherits from NSArray, so it can be passed to anywhere NSArray is expected (upcasting).
So you design your classes and expect them to be immutable, but you can't use NSArray anywhere. Because otherwise, it'll be mutable after all. You can do a runtime check as a workaround.
(I truly believe OOP should only be taught in computer science as a relic).
Swift is completely different. Standard arrays are structures, always mutable - value types passed by value
https://commonplacefacts.com/2022/07/27/principia-mathematic...
Note, also, that the article isn't even objective. It asserts that the definition of a subtype is Liskov's principle. However, Liskov's principle is only one of multiple possible definitions. In other words, the article is really only invoking Liskov's name as an appeal to authority. So much for strict logic.