IMHO implementing your proposal would close the door on some of the things you do when building in-memory dbs (T == U -> TRUE for T not related to U), which if swift remains for small apps is not a terrible loss, but may be more of an issue for one day doing big-data with it.
Regards (From mobile) > On Jul 18, 2016, at 12:21 PM, Johannes Neubauer via swift-evolution > <[email protected]> wrote: > > 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 _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
