<div dir="ltr">This is something I've wanted for a while (ever since basic equality was added to tuples), and I've considered writing a proposal but never had the time to jot something down. I'm glad other people have had the same thoughts. I've become frustrated at having to write the switch-case-let boilerplate for enums, especially.<div><br></div><div>I'd like to see the following rules:</div><div><br></div><div>For structs:</div><div>- A struct should implicitly conform* to Equatable if all of its fields conform (either explicitly or implicitly by these rules) to Equatable. The compiler will auto-generate an implementation that is simply the AND of the field-wise comparisons.</div><div>- A struct should implicitly conform to Hashable if all of its fields conform (exp. or imp.) to Hashable. The compiler will auto-generate an implementation that computes a hash value using a universal hash function (say, Knuth's) based on the hash values of its fields. (Order matters here, so declaration order?)</div><div><br></div><div>For enums:</div><div>- An enum should implicitly conform to Equatable if all of the types of all associated values across all cases conform to Equatable. The compiler will auto-generate an implementation that switches on the case and if they are the same, compares the associated values.</div><div>- An enum should implicitly conform to Hashable if all of its fields conform (exp. or imp.) to Hashable. The compiler will auto-generate an implementation that computes a hash value using a universal hash value where the first term is the case's ordinal (position in declaration order) followed by terms coming from its associated values' hash values.</div><div><br></div><div>I'm not 100% sold on Comparable being a good idea to support here; when implementing Comparable over multiple fields, there's often a specific order that matters—you encounter a pair of fields that are equal so you move on to the next one. I don't think we want to tie that to field declaration order or anything like that... it seems to surprising. But it would be nice to get rid of that boilerplate as well.</div><div><br></div><div>* When I say "implicitly conform" above, I'm torn about whether that should mean:</div><div>- the struct or enum doesn't have to list Equatable/Hashable at all, but it gets it anyway (kind of like how enums that extend a scalar type get RawRepresentable automatically), or</div><div>- the struct or enum gets implicit implementations of ==/hashValue, but you still have to explicitly declare that it conforms to Equatable/Hashable</div><div><br></div><div>On the one hand, getting the conformance implicitly matches how RawRepresentable is already treated, and makes getting the conformance zero effort. On the other hand, it makes error handling trickier: if you add a non-Equatable/non-Hashable field or associated value to a struct/enum, all of your call sites break. (I guess they would even if you declared the conformance, but at least there you'd also get the "Type does not conform to Equatable/Hashable" error at the struct/enum itself, and the compiler could even potentially flag the offending field/associated value that's causing the conformance to fail.) Thoughts?</div><div><br></div><div>If there's interest, I'd be happy to put this into the actual proposal template.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, May 24, 2016 at 8:46 AM Mark Sands via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I apologize upfront for necromancing this thread. Is there any momentum on this proposal?<div><br></div><div>My team was discussing the merits of default (opt-in) Equality. As soon as the equality function has been written then the compiler is satisfied, but there is no way to get compile time correctness for the equality. Unit tests can only go so far with ensuring the equality function is robust. Once a new property is added to a struct, for instance, the equality function is no longer correct and without warning. Currently there is no way to safeguard this situation. This would be a welcome addition to Swift.</div><div><br></div><div>Mark</div><div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 11, 2016 at 11:19 AM, Jose Cheyo Jimenez via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span>
> (starting a new thread by DaveA's request)<br>> <br>> There's a definition of equality that makes sense as a default for nearly every type in our system:<br>> <br>> - Basic types like IntNN, FloatNN, String, etc. have domain-defined equality,<br>> - Structs and tuples can be considered equal if their corresponding fields are equal,<br>> - Enums can be considered equal if they carry the same, equal payload,<br><div><br></div></span><div>+1 for Equality, Comparable and Hashable especially for enums and tuples. </div><div><br></div><div>I know that equality was added for tuples but I think that enums are perfect for adding automatic generation of conformance to Equality, Comparable and Hashable. </div><div><br></div><div>Take a look at this toy example of an Enum with 9 cases</div><div><br></div><div>boiler plate to conform to Equatable</div><div><a href="https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L151-L189" target="_blank">https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L151-L189</a></div><div><br></div><div>boiler plate to conform to Comparable</div><div><a href="https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L191-L245" target="_blank">https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L191-L245</a></div><span><div><br></div><div><br></div><div>> It's my feeling that Equatable and Hashable would make a lot of sense as universal operations; I'm not so sure about Comparable.<br>> <br>> -Joe</div><div><br></div></span><div><div>For enums a defaultComparable protocol could just rank on the order the fields are declared:</div></div><div><a href="https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L211-L212" target="_blank">https://github.com/exercism/xswift/blob/master/exercises/poker/PokerExample.swift#L211-L212</a></div><div><br></div><div><br></div></div><br>_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div></div></div>
_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>