> On Mar 14, 2017, at 1:08 PM, Karl Wagner <[email protected]> wrote:
> 
> 
>> On 14 Mar 2017, at 19:30, Joe Groff via swift-evolution 
>> <[email protected]> wrote:
>> 
>> 
>>> On Mar 14, 2017, at 11:27 AM, David Hart <[email protected]> wrote:
>>> 
>>> 
>>> 
>>>> On 14 Mar 2017, at 16:41, Joe Groff via swift-evolution 
>>>> <[email protected]> wrote:
>>>> 
>>>> 
>>>>> On Mar 13, 2017, at 8:38 AM, Vincent Esche via swift-evolution 
>>>>> <[email protected]> wrote:
>>>>> 
>>>>> Source compatibility
>>>>> 
>>>>> Making use of "extending protocols to conform to protocols":
>>>>> 
>>>>> extension Hashable: HashVisitable 
>>>>> {
>>>>> 
>>>>> func hash<H: Hasher>(_ hasher: inout
>>>>> H) {
>>>>> 
>>>>> self.hashValue.hash(&
>>>>> hasher)
>>>>>  }
>>>>> }
>>>> 
>>>> We're unlikely to add this feature soon. It seems reasonable to me to 
>>>> instead have `HashVisitable` refine `Hashable` and provide a default 
>>>> implementation of `hashValue` using a default hasher. I think we still 
>>>> want `Hashable` to be the currency protocol most APIs work with for 
>>>> performance in unspecialized code, since we could inline the visitation 
>>>> and hasher implementation together inside the specialized `hashValue` 
>>>> witness.
>>> 
>>> Can you explain the performance argument? How does it fare (in your 
>>> opinion) compared to the arguments in the proposal?
>>> 
>>> How about:
>>> 
>>> protocol Hashable {
>>>   func hash<H: Hasher>(with hasher: inout H)
>>> }
>>> 
>>> extension Hashable {
>>>   var hashValue: Int {
>>>       var hasher = StdLibDefaultHasher()
>>>       hash(with: hasher)
>>>       return hash.finish()
>>>   }
>>> }
>> 
>> For unspecialized code that takes a generic T: Hashable, that will place the 
>> only dynamic dispatch point on `hash`, so that will place an abstraction 
>> barrier between the Hasher and Self type being hashed, so would likely mean 
>> a dynamic call for every component of the value being hashed. Having 
>> `hashValue` be a dynamic dispatch point allows the hasher to be inlined 
>> together with the type's visitor implementation.
>> 
>> -Joe
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> Couldn’t we solve that by adding hashValue with the protocol requirements 
> (and with a default implementation)? IIRC, the standard library already does 
> this for things like map. They are defined as requirements even though they 
> are completely optional in practice.
> 
> protocol Hashable {
>   func hash<H: Hasher>(with hasher: inout H)
>   var hashValue: Int { get }
> }
> 
> extension Hashable {
>   var hashValue: Int {
>       var hasher = StdLibDefaultHasher()
>       hash(with: hasher)
>       return hash.finish()
>   }
> }

Sure, that would be fine. Introducing HashVisitable as a new protocol refining 
Hashable might make it easier to introduce later without disturbing the ABI.

-Joe
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to