<div dir="ltr">The documentation bug is not the sole motivation for the proposal.<div>I did in fact only find it while writing the accompanying <a href="https://blog.definiteloops.com/ha-r-sh-visitors-8c0c3686a46f">blog post</a>,</div><div>in which I present a couple of additional motivations besides hash collisions.<div><br></div><div>Namely:</div><div>- decoupling</div><div>- independence from a one-size-fits-all hasher impl</div><div>- multiple hashers per instance (for implementing Bloom Filters, etc.)</div><div>- different hashers for different use-cases (fast&amp;weak for safe bottlenecks, slow&amp;secure for web-exposed APIs)</div><div>- …</div><div><br></div><div>I’m actually much more interested in the independence gained, than pure performance.</div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 14, 2017 at 2:44 AM, Xiaodi Wu <span dir="ltr">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="h5">On Mon, Mar 13, 2017 at 8:30 PM, Tony Allevato via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Adding the list back to this reply because I don&#39;t believe you meant to reply only to me, and I think it&#39;s an important discussion to have :)</div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">On Mon, Mar 13, 2017 at 4:32 PM Vincent Esche &lt;<a href="mailto:regexident.mailinglists@gmail.com" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">regexident.mailinglists@gmail<wbr>.com</a>&gt; wrote:<br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg">Automatic generation of Hashable implementation code only &quot;solves&quot; the problem of having to implement `var hashValue`.<div class="m_3098743135821430340m_8773111132439994424gmail_msg">It however only works for some types. By no means for all.</div></div></blockquote><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div></div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Certainly, and I never suggested that it would work for every case. I was responding to Sean&#39;s point that the compiler should be able to do &quot;good enough&quot; in the common cases and I offered a way that that can be achieved.</div></div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Take this hypothetical implementation of a HSB color:</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg">struct Color {</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><span class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038gmail-Apple-tab-span m_3098743135821430340m_8773111132439994424gmail_msg" style="white-space:pre-wrap">        </span>let hue: UInt8</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><span class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038gmail-Apple-tab-span m_3098743135821430340m_8773111132439994424gmail_msg" style="white-space:pre-wrap">        </span>let saturation: UInt8</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><span class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038gmail-Apple-tab-span m_3098743135821430340m_8773111132439994424gmail_msg" style="white-space:pre-wrap">        </span>let brightness: UInt8</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">}</div></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Let the semantic of this type be this:</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Any two colors with a `brightness` of `0` are to be considered equal regardless of their respective `hue` or `saturation`. At night all cats are gray. </div></div></blockquote><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">An auto-generated conformance impl for `Color` would most likely be wrong afaict.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">And those kind of semantics are everywhere.</div></div></blockquote><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div></div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Of course, and in those cases, you wouldn&#39;t want to use an auto-derived Equatable or Hashable implementation. Those kinds of semantics are &quot;everywhere&quot; for certain definitions of &quot;everywhere&quot;, but similarly, semantics where the hash value of a thing can be determined simply via combination of the hash values of its components are also &quot;everywhere&quot;.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">I wouldn&#39;t suggest that auto-deriving Hashable solves *all* problems, and similarly, your proposal doesn&#39;t help in the situation you described either. Your API provides a different way to mix the hue, saturation, and brightness components in an implementation of hashValue, but it doesn&#39;t force the user to mix them *correctly* (by excluding hue/saturation if brightness is zero).</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">So in both cases, users still have to provide custom implementations of == and hashValue. But without auto-deriving, users have to provide them even for the cases where the auto-derived implementation *would have been correct.*  Auto-deriving is about reducing the number of types that need to have custom implementations, thereby reducing the chance that a user will do it wrong.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">When considering a type with auto-derived Hashable and Equatable, there are two ways it can be wrong:</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">1) The auto-generated implementations of both == and hashValue don&#39;t honor the semantic contract of the type (for example, don&#39;t ignore brightness when it&#39;s zero).</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">2) The user overrides the auto-generated implementation of one of ==/hashValue but not both, and violates the contracts between them.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">For #1, yes, the compiler generated an incorrect implementation in that case. However, I would argue it&#39;s the developer&#39;s responsibility to fix it by overriding it if they need different semantics. As I mentioned above, without derivation, the developer could still implement it incorrectly, just as they could with your API.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">For #2, this could be solved by requiring users to override both if they override one of them. Now they&#39;re back in the same situation as #1—they either did it right, or they did it wrong.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div></div></div><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"> </div><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Auto-generation clearly is no panacea when it comes to hashing. Especially if it leads to invalid and unsafe default implementations.</div></div></blockquote><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Auto-deriving cannot produce &quot;unsafe&quot; implementations because it&#39;s defined in terms of a function operating over the hash values of its components. It can produce an implementation that does not match the intended semantics of the class that are defined outside of its component values, but that&#39;s not the compiler&#39;s job to decide; it&#39;s up to the user to provide those.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Regarding unsafety, it&#39;s worth noting that your ContiguouslyHashable protocol is inherently unsafe and fragile. Imagine that a user implements a struct that they make conform to ContiguouslyHashable because at the time, it&#39;s a simple fixed layout type with primitive fields. If they take that type and add a new field to it that isn&#39;t contiguously hashable (say, a class reference) and they forget to replace the ContiguouslyHashable conformance, they now have a very broken type, and that behavior isn&#39;t caught until *runtime* when things go wrong.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">At least with derived conformances, in that situation the *compiler* would see that the type was no longer hashable and emit an error when it&#39;s used anywhere that Hashable/hashValue was expected.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">So if safety is your motivation, ContiguouslyHashable kind of fights back against that because it gives the user a door they can open—in some cases, accidentally—that produces invalid results.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"> </div><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">It would however be nice to be able to annotate types for which you want HashVisitable implementations to be generated.</div></div></blockquote><div><br></div><div>That&#39;s one of the still-open questions from the last discussion thread on the topic; whether auto-deriving should be automatic for any type where it is possible (as it is now for enums without associated values) or whether the user should have to opt-in.</div><div><br></div><div> </div><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">I actually don&#39;t see auto-generation as an alternative to a proper hashing API. But rather as an addition.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">HashVisitable and auto-deriving would actually work great together!</div></div></blockquote><div><br></div><div>I completely agree that these ideas complement each other very well! And I also agree that the language would do well to make it easier for users to easily do the right thing. I just feel that *the API proposed here specifically* adds too much complexity for the problem it&#39;s trying to solve.</div><div><br></div><div>I&#39;d find it more compelling if it was simplified a bit:</div><div><br></div><div>* The standard library doesn&#39;t need to provide a number of hash implementations; it should just provide one that works &quot;well enough&quot; in most cases</div><div>* Hashable doesn&#39;t have tie itself to a visitor pattern. It&#39;s not necessarily safer because users can still mix the wrong values; in that case, I&#39;d rather the stdlib implementation of the &quot;good enough&quot; hash just be a standalone mixer that the language can encourage users to use.</div></div></div></div></blockquote><div><br></div></div></div><div>I agree with this assessment. If SipHash is deemed &quot;good enough,&quot; then Swift should offer these as standalone facilities and encourage users to call them in `Hashable`. I think the API design proposed here is much too complex, but offering tried-and-true hash functions is certainly reasonable and would be an improvement over xor.</div><div><br></div><div>Certainly also, the documentation for `Hashable` can be improved. In general, however, it&#39;s not very convincing to motivate an entire proposal for a new feature based on a documentation bug. Recognize that there are (or at least have been, in past shipped versions of Swift) code snippets in the documentation that _don&#39;t even compile_! If we accepted the logic put forward here, we should give up on Swift entirely; after all, if even the official Swift documentation can&#39;t provide code that compiles, what hope do the rest of us have?!</div><div><div class="h5"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">In fact they <a href="https://is.gd/iy5770" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">already do in other languages</a>.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div></div><div><div class="m_3098743135821430340h5"><div class="gmail_extra m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg">On Mon, Mar 13, 2017 at 8:51 PM, Tony Allevato via swift-evolution <span dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg">&lt;<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br class="m_3098743135821430340m_8773111132439994424gmail_msg"><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg">I&#39;m not convinced this is the right approach: it couples the fact that a type is hashable with a specific strategy for implementing the hash value computation. <div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">Instead, the language should make efforts to avoid requiring the user to think about hashing algorithms *at all*; to answer Sean&#39;s question a couple messages up, I&#39;ve <a href="https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">proposed in the past</a> (rough working draft) adding derivation of Equatable and Hashable for structs and enums where it&#39;s possible to automatically do so (for example, if all of the enum&#39;s associated values are Equatable/Hashable). I&#39;ve been experimenting with an implementation in the compiler and I have something that works for enums, except for recursive ones. I haven&#39;t started structs yet because I think there are more open questions there, and I hope to propose enums and structs independently so that the enum one doesn&#39;t get bogged down by the struct one.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">The core team seems to be aware of the need for this; the logic that derives Equatable/Hashable for enums without associated values also has TODO comments to handle those with associated values, and to handle structs as well. Slava Pestov mentioned a while back that they encouraged PRs on it, which is why I started, but my free time has been limited lately.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><div class="m_3098743135821430340m_8773111132439994424gmail_msg">That being said, I *do* think there would be value in having some kind of hash &quot;mixer&quot; as part of the standard library and strongly encouraging through documentation that hashValue implementors use it. Getting the function right is the hard part, and if Swift both (1) took care of it for you by default in many cases and (2) made the harder cases easier by providing a high quality canned implementation, I think we&#39;d have a much cleaner solution than what is being proposed here.</div><div class="m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div></div><div class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038HOEnZb m_3098743135821430340m_8773111132439994424gmail_msg"><div class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038h5 m_3098743135821430340m_8773111132439994424gmail_msg"><br class="m_3098743135821430340m_8773111132439994424gmail_msg"><div class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg"><div dir="ltr" class="m_3098743135821430340m_8773111132439994424gmail_msg">On Mon, Mar 13, 2017 at 12:18 PM Sean Heber via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div><blockquote class="gmail_quote m_3098743135821430340m_8773111132439994424gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Is there any reason the API couldn’t be expressed as something along these lines?<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
func hash() -&gt; [Hashable] {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
  return [x, y]<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
l8r<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
Sean<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt; On Mar 13, 2017, at 2:15 PM, David Hart &lt;<a href="mailto:david@hartbit.com" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">david@hartbit.com</a>&gt; wrote:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; On 13 Mar 2017, at 18:54, Sean Heber via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; I’m dumb when it comes to proper hashing, but it’s such a tediously common thing in my experience to need to add Hashable to some kind of a struct so I can stash it in a set or use it as a dictionary key. Is there really no way to make this all more automatic? I have to be honest - this proposal seems *harder* to understand than the way it works now.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt; It&#39;s not really harder: just call hash on each of your type&#39;s significant values:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt; x.hash(&amp;hasher)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt; y.hash(&amp;hasher)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt; How would you implement hashValue in a simpler way, remembering that &#39;x ^ y&#39; is an incorrect implementation?<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; Of course the easiest would be if the language could just do this “good enough&quot; for me using reflection or whatever and if I really did run into a problem where I wanted to do this myself, I could override something.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; Perfect is the enemy of good.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; l8r<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; Sean<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; On Mar 13, 2017, at 10:38 AM, Vincent Esche via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Hi there,<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; I&#39;ve written up a proposal for an overhaul/replacement of the Hashable protocol and would love to hear your feedback on it!<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Rendered | Blog Post<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Cheers,<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Vincent<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Ps: I&#39;d like to thank David Hart (@hartbit) for his great editorial feedback on this proposal. 👍<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; HashVisitable<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   • Proposal: SE-NNNN<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   • Authors: Vincent Esche<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   • Review Manager: TBD<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   • Status: Awaiting review<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Introduction<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Replace the Hashable protocol by two new procotols (Hasher and HashVisitable) to improve safety, versatility and learnability.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Motivation<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Implementing Hashable is difficult and the consequences if not done well have dire performance and safety repercussions.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; The documentation of Hashable lists a sample implementation of var hashValue:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; /// A point in an x-y coordinate system.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; struct GridPoint {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   var x: Int<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   var y: Int<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension GridPoint: Hashable {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   var hashValue: Int {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       return x.hashValue ^ y.hashValue<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   static func == (lhs: GridPoint, rhs: GridPoint) -&gt; Bool {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       return lhs.x == rhs.x &amp;&amp; lhs.y == rhs.y<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Calculating the hashes of all GridPoints (given the above implementation) on a 1000 × 1000 grid …<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; let (width, height) = (1000, 1000)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; let total = width * height<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; var hashes = Set&lt;Int&gt;()<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; for x in 0..&lt;width {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   for y in 0..&lt;height {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       hashes.insert(GridPoint(x: x, y: y).hashValue)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; print(&quot;\(hashes.count) unique hashes out of a total of \(total).&quot;)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; … results in just 1024 unique hash values for 1_000_000 unique values.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; In other words: The recommended implementation causes 99.9% of values to trigger a hash collision.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Out of those 1_000_000 values the median collision count was 976 with min and max being 976 and 1000respectively.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; The collision rate will have negative impact in algorithms which heavily use hashValue like the ones in Dictionaryand Set. Furthermore, it increases the vulnerability to DDOS attacks when exposed to the web.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; If even the official Swift documentation gets the implementation of hashValue wrong, then who is to expect the average Swift programmer to do any better?<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; In contrast, running the same snippet using HashVisitable and the semi-secure Fnv1aHash (see below) results in zero collisions!<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Finally, the design of the Hashable protocol forces the use of one implementation without the possibility of switching between multiple hashing algorithms.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Proposed solution<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Instead of coupling the hashing algorithm with each and every Swift type, we should provide a hashing API based on the visitor-pattern. By freeing application developers from the burden of having to implement hashing algorithms, the Standard Library can provide default ones which fulfill collision, performance and security goals. Furthermore, it would allow developers to swap to different algorithms based on the use case.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Detailed design<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; The proposal deprecates the Hashable protocol and introduces the following two:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; protocol Hasher<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; mutating func finish() -&gt; Int<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; mutating func write(bytes<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; : UnsafeRawBufferPointer)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; protocol HashVisitable<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; func hash&lt;H: Hasher&gt;(_ hasher: inout<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; H)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Hasher is the protocol which represents a hashing algorithm, and HashVisitable replaces Hashable. For types entirely represented by their memory layout, the following protocol would provide a default implementation:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; protocol ContiguouslyHashable: HashVisitable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension ContiguouslyHashable {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   func hash&lt;H: Hasher&gt;(_ hasher: inout H) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       var mutableSelf = self<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       try! Swift.withUnsafeBytes(of: &amp;mutableSelf) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;           hasher.write(bytes: $0)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Bool : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension UInt8 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension UInt16 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension UInt32 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension UInt64 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension UInt : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Int8 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Int16 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Int32 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Int64 : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Int : ContiguouslyHashable {}<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; The Standard-Library would then provide a set of hashing implementations specific to each purpose. A possible choice for hashing algorithms would be the reasonably fast SipHash-2-4, and the reasonably secure SipHash-4-8.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; FNV-1A is another popular semi-secure but blazingly fast hash algorithm, which – for the sake of demonstration – could be implemented as follows:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; struct Fnv1aHash<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; fileprivate var state: UInt<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; init(seed: UInt<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; ) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; self.state = seed &amp;+ 14695981039346656037<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Fnv1aHash: Hasher<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; mutating func write(bytes<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; : UnsafeRawBufferPointer) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; for byte in<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; bytes {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; self.state = (self.state ^ UInt(byte)) &amp;* 1099511628211<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;       }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; mutating func finish() -&gt; Int<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; return unsafeBitCast(self.state, to: Int.self<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; )<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Coming back to the sample code present in the Hashable documentation, the new implementation would look like:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension GridPoint: HashVisitable<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; func hash&lt;H: Hasher&gt;(_ hasher: inout<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; H) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; self.x.hash(&amp;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; hasher)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; self.y.hash(&amp;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; hasher)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Source compatibility<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Making use of &quot;extending protocols to conform to protocols&quot;:<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; extension Hashable: HashVisitable<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; func hash&lt;H: Hasher&gt;(_ hasher: inout<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; H) {<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; self.hashValue.hash(&amp;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; hasher)<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;   }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; }<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Effect on ABI stability<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; n/a<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Effect on API resilience<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; This feature should be possible to add/remove without breaking ABI.<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; Alternatives considered<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; n/a<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; ______________________________<wbr>_________________<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; swift-evolution mailing list<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; <a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt;<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; ______________________________<wbr>_________________<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; swift-evolution mailing list<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; <a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
______________________________<wbr>_________________<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
swift-evolution mailing list<br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br class="m_3098743135821430340m_8773111132439994424m_1052664451246294635m_-2288818070518422038m_858664506594008476gmail_msg m_3098743135821430340m_8773111132439994424gmail_msg">
</blockquote></div>
</div></div><br class="m_3098743135821430340m_8773111132439994424gmail_msg">______________________________<wbr>_________________<br class="m_3098743135821430340m_8773111132439994424gmail_msg">
swift-evolution mailing list<br class="m_3098743135821430340m_8773111132439994424gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_3098743135821430340m_8773111132439994424gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_3098743135821430340m_8773111132439994424gmail_msg" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br class="m_3098743135821430340m_8773111132439994424gmail_msg">
<br class="m_3098743135821430340m_8773111132439994424gmail_msg"></blockquote></div><br class="m_3098743135821430340m_8773111132439994424gmail_msg"></div>
</div></div></blockquote></div></div></div>
<br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>