> 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
