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

Reply via email to