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

Reply via email to