[swift-evolution] [Draft] Hasher & HashVisitable

Joe Groff jgroff at apple.com
Tue Mar 14 13:30:45 CDT 2017


> On Mar 14, 2017, at 11:27 AM, David Hart <david at hartbit.com> wrote:
> 
> 
> 
>> On 14 Mar 2017, at 16:41, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 
>>> On Mar 13, 2017, at 8:38 AM, Vincent Esche via swift-evolution <swift-evolution at swift.org> 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


More information about the swift-evolution mailing list