> On 18 Jul 2016, at 08:04, Adrian Zubarev via swift-evolution 
> <[email protected]> wrote:
> 
> This is something additional, but I’m curios about how the community feels 
> about it.
> 
> I recently come across the issue where conforming to Hashable wasn’t enough 
> to thecke if two instances of the same generic type were equal.
> 
> I had additionally provide myself the != function.
> 
> public func !=<T, U>(lhs: SomeTypeName<T>, rhs: SomeTypeName<U>) -> Bool {
>     return lhs.hashValue != rhs.hashValue
> }
> I wondered if Swift can ever get generic specialization like this:
> 
> public func !=<T : Hashable, U, V>(lhs: T<U>, rhs: T<V>) -> Bool {
>     return !(lhs.hashValue == rhs.hashValue)
> }
> This function in stdlib would fill the gap. Or we need an extra protocol 
> GenericHashable which includes !=.
> 
What exactly is the problem you're trying to solve here? Hash values being 
equal is not a guarantee of equality, so what you're doing with this operator 
is masking what's going on which I'm not sure is a good idea. If you need to 
compare hash-values, then compare them, they're already as generic as you can 
possibly get (since they're always of type Int), otherwise you can't really 
rely on hash-values from generic types in this way, and shouldn't be hiding 
them behind the equality operator.

To think of it another way, if two hash-values are equal, then the two values 
*might* be equal, but you still have to test them further to be sure. You can 
only rely on the hash-value in this way if you have control of the 
implementation details, which you can only guarantee when the values you are 
comparing are the same type, or from a family of types that you control (as you 
say, a protocol could do this, by requiring that hash-values are unique within 
some well-defined domain).

I feel like this is seeking a solution that is a workaround to a protocol that 
has no associatedtype, as the problem you're describing is essentially already 
solved by generic constraints. For example, if you were working with Iterators 
you can define things like:

        func someFunc<I1:IteratorProtocol, I2:IteratorProtocol where 
I1.Element:Hashable, I2.Element:Hashable>(lhs:I1, rhs:I2) -> Bool {
                return lhs.next()?.hashValue == rhs.next()?.hashValue
        }

Probably a useless example, but it shows how generic constraints achieve this 
already, but they require a protocol that is intended to expose an internal 
detail (the Element associatedtype), this is not what Hashable is for, Hashable 
is for reducing any conforming type down to an Int, with no guarantee of that 
value being unique.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to