<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I’m skeptical that your use case is common enough to justify leaving open the glaring bug magnet that started this thread. Could you give an example of a common occurrence where it would be a significant improvement to explicitly write a *less precise* hash function that’s only “good enough” and still want the more precise full equality?&nbsp;<div class=""><br class=""></div><div class="">TBH, I think contributors here are often too quick to demand padding the walls to protect the most incompetent of engineers from themselves, but I feel like the root proposal here is a good idea.</div><div class=""><br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 15, 2017, at 9:59 PM, Tony Allevato via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Those are valid concerns for hashing algorithms in general, but there's no connection between that and a statement that an explicitly implemented hashValue should also require an explicitly implemented ==. Requiring that certainly doesn't make it less likely that people will run into the problem you've described if they implement their own hashValue—if they implement it poorly, it just means that the could also shoot themselves in the foot by then being forced to also implement == and possibly doing it poorly.</div></div></blockquote><div><br class=""></div>IMO, it’s far easier to implement hashValue poorly, so I think reminding the dev they need to think about `==` too is more helpful than not. I’m not often in favor of the padded cell, but I would even consider a proposal to emit a warning if fields read in `==` is a strict subset of fields read in `hashValue`.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""><div class=""><br class=""></div></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Dec 15, 2017 at 9:53 PM Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" class="">howard.lovatt@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="">I would say it is an advanced use because it is an optimisation and in addition an optimisation that requires a lot of knowledge of the fields to be certain that a reduced hash is going to be good enough.&nbsp;<div class=""><br class=""></div><div class="">The optimisation doesn’t have a great history, for example in Java they used to hash only the 1st 6 characters of a string. However this was exploited in denial of service attacks that generated a vast number of strings with the same hash value, i.e same 1st 6 characters, that then overwhelmed the dictionary (map in Java) used in the web server software to store logins.&nbsp;</div><div class=""><br class=""></div><div class="">So it wouldn’t be something I would encourage people to do or even worse do by accident.&nbsp;</div></div><div dir="auto" class=""><div class=""><br class=""><br class=""><div id="m_-7256071964309952508AppleMailSignature" class="">-- Howard.</div></div></div><div dir="auto" class=""><div class=""><div class=""><br class="">On 16 Dec 2017, at 3:36 pm, Tony Allevato &lt;<a href="mailto:tony.allevato@gmail.com" target="_blank" class="">tony.allevato@gmail.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Dec 15, 2017 at 6:41 PM Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" target="_blank" class="">howard.lovatt@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="">I think that is an advanced use, rather than a common use. I would prefer that to be something you manually code.&nbsp;</div></blockquote><div class=""><br class=""></div><div class="">But why? Why should implementing a subset of fields for hashValue require a developer to also manually implement == when the default synthesized version would be perfectly fine? The relationship between Equatable and Hashable does not go both ways.</div><div class=""><br class=""></div><div class="">In fact, requiring that they do so is *more* error prone because now they're being forced to implement something that the compiler would have otherwise generated for them.</div><div class=""><br class=""></div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class=""><br class=""><br class=""><div id="m_-7256071964309952508m_1702168286999014836AppleMailSignature" class="">-- Howard.</div></div><div dir="auto" class=""><div class=""><br class="">On 16 Dec 2017, at 7:08 am, Tony Allevato &lt;<a href="mailto:tony.allevato@gmail.com" target="_blank" class="">tony.allevato@gmail.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Fri, Dec 15, 2017 at 11:39 AM Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+1<br class="">
I think the simple solution of if you provide either == or hashValue you have to provide both is the best approach. Good catch of this bug.<br class="">
-- Howard.<br class=""></blockquote><div class=""><br class=""></div><div class="">That would be a significant usability hit to a common use case. There are times where a value is composed of N fields where N is large-ish, and equality is dependent on the values of all N fields but the hash value only needs to be "good enough" by considering some subset of those fields (to make computing it more efficient).</div><div class=""><br class=""></div><div class="">That still satisfies the related relationship between == and hashValue, but a user wanting to explicitly implement a more efficient hashValue should *not* necessarily be required to explicitly write the same == that would be synthesized for them in that case.</div><div class=""><br class=""></div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
&gt; On 16 Dec 2017, at 6:24 am, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt; +1. The proposal wasn’t explicit enough to have either supported or be against this IMO. It’s a sensible thing to spell out.<br class="">
&gt;<br class="">
&gt; Daniel Duan<br class="">
&gt; Sent from my iPhone<br class="">
&gt;<br class="">
&gt;&gt; On Dec 15, 2017, at 9:58 AM, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;&gt;<br class="">
&gt;&gt; SE-0185 is awesome, and brings the long-awaited ability for the compiler to provide a default implementation of `==` and `hashValue` when you don't provide one yourself. Doug and I were talking the other day and thought of a potential pitfall: what should happen if you provide a manual implementation of `==` without also manually writing your own `hashValue`? It's highly likely that the default implementation of `hashValue` will be inconsistent with `==` and therefore invalid in a situation like this:<br class="">
&gt;&gt;<br class="">
&gt;&gt; struct Foo: Hashable {<br class="">
&gt;&gt; // This property is "part of the value"<br class="">
&gt;&gt; var involvedInEquality: Int<br class="">
&gt;&gt; // This property isn't; maybe it's a cache or something like that<br class="">
&gt;&gt; var notInvolvedInEquality: Int<br class="">
&gt;&gt;<br class="">
&gt;&gt; static func ==(a: Foo, b: Foo) -&gt; Bool {<br class="">
&gt;&gt;&nbsp; &nbsp;return a.involvedInEquality == b.involvedInEquality<br class="">
&gt;&gt; }<br class="">
&gt;&gt; }<br class="">
&gt;&gt;<br class="">
&gt;&gt; As currently implemented, the compiler will still give `Foo` the default hashValue implementation, which will use both of `Foo`'s properties to compute the hash, even though `==` only tests one. This could be potentially dangerous. Should we suppress the default hashValue derivation when an explicit == implementation is provided?<br class="">
&gt;&gt;<br class="">
&gt;&gt; -Joe<br class="">
&gt;&gt; _______________________________________________<br class="">
&gt;&gt; swift-evolution mailing list<br class="">
&gt;&gt; <a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
&gt; _______________________________________________<br class="">
&gt; swift-evolution mailing list<br class="">
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div></div>
</div></blockquote></div></blockquote></div></div>
</div></blockquote></div></div></blockquote></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>