[swift-evolution] [Draft] Hasher & HashVisitable
Joe Groff
jgroff at apple.com
Tue Mar 14 15:10:25 CDT 2017
> On Mar 14, 2017, at 1:08 PM, Karl Wagner <razielim at gmail.com> wrote:
>
>
>> On 14 Mar 2017, at 19:30, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>
>>> 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
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> 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
More information about the swift-evolution
mailing list