> Brent, I think it's even slightly more complicated than that. Think e.g. how
> two subclass instances of NSArray should compare equal even if they've got
> different types. (I really dislike class inheritance for these reasons, but
> below is my take on how we could better live with the issue in Swift.)
If you're referring to this:
>> guard let other = other as? Self else {
>> return super == other
>> }
I probably should have said `#Self`, meaning e.g. `NSArray` if you're
implementing `NSArray.==`. What you really want to test for there is the
*static* type of `self`, not the dynamic type.
If you're referring to the multiple dispatch thing, I actually think that will
handle subclassing perfectly well. If you have a class hierarchy like this,
with each class implementing its own `(Self, Self)` equality operation:
NSObject
NSArray
MyArray
MyOtherArray
Then using `==` on `MyArray` and `MyOtherArray` should use `(NSArray,
NSArray).==()`, which presumably would compare the length and elements to test
for equality.
> For the very example of Equatable and Foundation classes, we would get the
> right behaviour for NSObject's `isEqual` by changing the definition of
> Equatable into:
>
> protocol Equatable {
> associatedtype EqualSelf = Self // the default is ok pretty much
> always
> func == (lhs: Self, rhs: EqualSelf) -> Bool
> func != (lhs: Self, rhs: EqualSelf) -> Bool
> }
>
> This way, the compiler would always be looking for the `(Self, NSObject) ->
> Bool` shape of operation, which actually picks up statically the correct
> overload for `lhs.isEqual(rhs)`.
But you would need to do this for all operators. A protocol that requires `<`
or `+` would need to de-privilege the right-hand side in exactly the same way.
--
Brent Royal-Gordon
Architechies
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution