[swift-evolution] Proposals: (1) Forbidding custom `==` for value types, (2) `dispatch` keyword, (3) `default`-result for methods with `Self`, and (4) Poor-Mans-Existentials
Johannes Neubauer
neubauer at kingsware.de
Sat Jul 16 08:18:42 CDT 2016
Dear Saagar,
> Am 15.07.2016 um 19:05 schrieb Saagar Jha <saagarjha28 at gmail.com>:
>
> Equatable, where the == operator is defined, will not let you compare two things of a different type.
This is not true for reference types. Consider the following **bad** (but compiling code):
```swift
class A: Equatable {}
class Aa: A {
let a: Int
init(a: Int) {
self.a = a
}
}
func ==(lhs: A, rhs: A) -> Bool {
return lhs === rhs
}
func ==(lhs: Aa, rhs: Aa) -> Bool {
return lhs.a == rhs.a
}
```
Now let us use this:
```swift
let a = A()
let a2 = A()
let aa = Aa(a: 0)
let aa2 = Aa(a: 1)
let aa3 = Aa(a: 1)
// prints `true`
print(a == a)
// prints `false`
print(a == a2)
// prints `false`
print(a == aa)
// prints `false`
print(a == aa3)
// prints `false`
print(aa == aa2)
// prints `true` because it compares the `a: Int` values.
print(aa2 == aa3)
// now mixed-type comparison (returns `false`)
print(a == aa2)
```
Hence, you can do mixed-type equality checks in Swift. Even worse is, you can do this:
```swift
let aa2AsA: A = aa2,
aa3AsA: A = aa3
// prints `true` because it compares the `a: Int` values.
print(aa2 == aa3)
// prints `false`, because the equals method of `A` is used
print(aa2AsA == aa3AsA)
```
Just by assigning an object to a variable that is typed differently the result is completely different. This is because method parameters are dispatched statically. This is fast, but results in really unintended results, you can do a **lot** of things breaking the contract of `==` with that. This is why I wanted to add a `default` clause (in *3.* of my original proposal) for such methods involving two references to `Self`. Further on, I wanted to add the keyword `dispatch` for method (and operator) parameters, where dispatching is necessary (see *2.* of my original proposal).
I think these changes are crucial for the safety of the language. Now you can write really bad code and the compiler/IDE doesn’t help you. You may do the dynamic dispatch manually, but this is error-prone (and many developers aren’t even aware of the issue).
All the best
Johannes
More information about the swift-evolution
mailing list