<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=""><div class="">Hi Andrew,&nbsp;</div><div class=""><br class=""></div><div class="">Implicitly making Tuples Hashable should be its own proposal. Take a look at the Equable Tuple proposal as a template.&nbsp;</div><div class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md</a></div><div class=""><br class=""></div><div class="">Thanks</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On May 9, 2017, at 3:45 PM, Andrew Bennett 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=""><div class="">You state that you will not synthesise conformance for tuples, I agree with this, but if a struct or enum holds a tuple it would be nice if it could be hashed if its members are all hashable.</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo; color: rgb(4, 51, 255);" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> A {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(4,51,255)" class="">var</span><span style="font-variant-ligatures:no-common-ligatures" class=""> a: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">, b: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">, c: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo; min-height: 13px;" class=""><span style="font-variant-ligatures:no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo; color: rgb(4, 51, 255);" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> B {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">&nbsp; </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(4,51,255)" class="">var</span><span style="font-variant-ligatures:no-common-ligatures" class=""> tuple: (a: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">, b: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">, c: </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,149,175)" class="">Int</span><span style="font-variant-ligatures:no-common-ligatures" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures" class="">}</span></div></div><div class=""><span style="font-variant-ligatures:no-common-ligatures" class=""><br class=""></span></div><div class="">I'd consider these two to be equivalent as far as this proposal is concerned, it would be nice if the proposal made that explicit.</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, May 9, 2017 at 7:17 AM, Tony Allevato via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><br class=""><br class=""><div class="gmail_quote"><span class=""><div dir="ltr" class="">On Mon, May 8, 2017 at 2:11 PM Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.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 style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class="">On May 8, 2017, at 4:02 PM, Tony Allevato &lt;<a href="mailto:tony.allevato@gmail.com" target="_blank" class="">tony.allevato@gmail.com</a>&gt; wrote:</div><br class="m_-4206921585179370676m_7114657150419324378Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_quote"><div dir="ltr" class="">On Sat, May 6, 2017 at 4:17 PM Chris Lattner &lt;<a href="mailto:clattner@nondot.org" target="_blank" class="">clattner@nondot.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"><div style="word-wrap:break-word" class="">On May 5, 2017, at 11:33 AM, Tony Allevato via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><br class="m_-4206921585179370676m_7114657150419324378m_-6169955689964255263Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">Can the opt-in conformance be declared in an extension?&nbsp; If so, can the extension be in a different module than the original declaration?&nbsp; If so, do you intend any restrictions, such as requiring all members of the type declared in a different module to be public?&nbsp; My initial thought is that this should be possible as long as all members are visible.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Declaring the conformance in an extension in the same module should definitely be allowed;</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">Please follow the precedent of the Codable proposal as closely as possible.&nbsp; If you’d like this to be successful for Swift 4, you should look to scope it as narrowly as possible.&nbsp; Because it is additive (with opt-in), it can always be extended in the future.</div></div></div><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_quote"><div class=""> I believe this would currently be the only way to support conditional conformances (such as the `Optional: Hashable where Wrapped: Hashable` example in the updated draft), without requiring deeper syntactic changes.</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">This proposal doesn’t need to cover all cases, since it is just sugaring a (very common) situation.&nbsp; Conditional conformances to Hashable could be written manually.</div></div></div><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_quote"><div class="">I'm less sure about conformances being added in other modules,</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">It is a bad idea, it would break resilience of the extended type.</div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_quote"><div class="">But after writing this all out, I'm inclined to agree that I'd rather see structs/enums make it into Swift 4 even if it meant pushing classes to Swift 4+x.</div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class="">Agreed, keep it narrow to start with.</div><br class=""></div><div class="">Also, I don’t know how the rest of the core team feels about this, but I suspect that they will be reticent to take an additive proposal at this late point in the schedule, unless someone is willing to step up to provide an implementation.</div></div></blockquote><div class=""><br class=""></div><div class="">That someone is me :) &nbsp;I have a branch where it's working for enums (modulo some weirdness I need to fix after rebasing a two-month-old state), and adapting that logic to structs should hopefully be straightforward after that. Going with the more narrowly-scoped proposal and making conformances explicit simplifies the implementation a great deal as well (I was previously blocked with recursive types when it was implicit).</div><div class=""><br class=""></div><div class="">Thanks for the feedback—after consideration, I've pulled classes out of the proposal completely (even non-final) and mentioned the other limitations so we'd have a record of what was discussed in this thread.</div><div class=""><br class=""></div><div class="">I've created a PR for the proposal text, in the event that the core team is interested in moving this forward:&nbsp;<a href="https://github.com/apple/swift-evolution/pull/706" target="_blank" class="">https://github.com/<wbr class="">apple/swift-evolution/pull/706</a></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div style="word-wrap:break-word" class=""><div class="">Thanks for continuing to push this forward Tony!&nbsp; The current proposal looks like the right approach for getting this into Swift 4. &nbsp;</div><div class=""><br class=""></div><div class="">I only have one question which I will present with an example:</div><div class=""><br class=""></div><div class="">protocol Foo: Equatable {}</div><div class="">protocol Bar: Hashable {}</div><div class=""><br class=""></div><div class="">struct FooType: Foo {}</div><div class="">struct BarType: Bar {}</div><div class=""><br class=""></div><div class="">Do FooType and BarType receive synthesis?</div></div></blockquote><div class=""><span style="font-size:13px" class=""><br class=""></span></div></span><div class=""><span style="font-size:13px" class="">Great question! Yes they should. It's "explicit" transitively since the answer to "does FooType/BarType conform to Equatable/Hashable?" is still "yes". (And I've confirmed that my prototype handles this case.)</span><br class=""></div><div style="font-size:13px" class=""><br class=""></div><div class=""><span style="font-size:13px" class="">This is especially helpful since Hashable extends Equatable, so a user only needs to list conformance to the former to get correctly synthesized implementations of both, which helps to guarantee that they're implemented consistently with respect to each other.</span></div><div class=""><span style="font-size:13px" class=""><br class=""></span></div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_quote"><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 style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div><br class=""></div></blockquote></div></div>
</div></blockquote></div><br class=""></div></blockquote></div></div>
<br class="">______________________________<wbr class="">_________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" 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/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
<br class=""></blockquote></div><br class=""></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=""></body></html>