> 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
