See below... > Am 18.07.2016 um 12:08 schrieb Johannes Neubauer via swift-evolution > <[email protected]>: > > Dear Félix, > > As a small follow-up, because you asked what I am protecting you from. > Dictionaries and Sets, for instance, will work only, if equality and hash > value are computed contract conform. As soon as you let (unintendedly) > differing values collapse or same values break up, you will have unintended > behavior. This is crucial and I think every developer should be thankful for > any help he gets here from a language. If (in the future) the swift runtime > will create value pools for you, and you have a wrong implementation of > equality, the complete system will just misbehave. **That** will be bugs hard > to find. > > All the best > Johannes > >> Am 18.07.2016 um 11:50 schrieb Johannes Neubauer via swift-evolution >> <[email protected]>: >> >> >>> Am 18.07.2016 um 03:51 schrieb Félix Cloutier <[email protected]>: >>> >>> Your initial rationale no longer makes sense with your suggested solution. >>> If the dumb comparison returns false, people can still introduce side >>> effects in the comparison method, except that now it's even harder to find >>> out because all of my equality tests have been rewritten as "memcmp(a, b) >>> || ==(a, b)“. >> >> No its `memcmp(a, b) && ==(a,b)`, since if the „standard equality“ says >> `true` there is no short-circuit, but the custom implementation has to be >> `true` either! It is just a pre-condition.
Sorry, wrote this in a hurry. It is `||` of course. But still the rest holds. >> >>> What are you trying to protect me from? >> >> 1. You cannot say something is unequal although the system says it is equal >> 2. You do not have to implement equality for value types, only if you really >> need custom behavior (so you do not write boiler-plate code, which is error >> prone), so side effects will be less common >> 3. With unique indirect storage (and copy-on-write) you would be able use >> `==` for large values, because these values are only shared for reads not >> for writes (future, not yet available in swift), so no race conditions >> 4. With `dispatch` in operator-methods (or any other) as well as a `default` >> clause for reference types, so that equality of mixed-types just result in >> `false`, so that this is not possible anymore (see excerpt of discussion): >> >>> Am 16.07.2016 um 15:18 schrieb Johannes Neubauer via swift-evolution >>> <[email protected]>: >>> >>> 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). >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
