<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""><span class=""></span></div><div class="">Thanks for this, Brent, you make a strong case! I didn't include a change to Collection.Index simply because it doesn't look like missing the constraint is really causing harm, just inconvenience. That said, you’re right that making something Hashable is easier than ever, and if we’re going to make this change, the time is now.<div class=""><br class=""></div><div class="">I tried adding the constraint in a branch, and it isn't quite as simple as I had expected. For one thing, CountableRange and CountableClosedRange need the Bound type to be Hashable, not just Strideable, which increases the number of places that could be source breaking. You can see the full diff here:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span><a href="https://github.com/apple/swift/pull/12944" class="">https://github.com/apple/swift/pull/12944</a></div><div class=""><br class=""></div><div class="">Also complicating things is that I don’t know what the migration path would look like—we can’t use availability attributes on associated type constraints, so it could be very difficult to support compiling both existing Swift 4 code and code that works on a compiler that requires the Hashable constraint.</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><div class=""><!-- signature open -->Nate<!-- signature close --></div><div class=""><br class="">On Nov 9, 2017, at 7:12 PM, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 9, 2017, at 4:29 AM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;">Why not? Specifically, why shouldn't we require `Hashable` conformance on indices? Adding it would require changes to conforming types, sure, but indices are already required to be `Equatable`, and `Hashable` conformance just got really easy to add, and custom `Collection`s are a relatively rare and advanced feature.</blockquote><div dir="auto" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div dir="auto" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">For a source-breaking change, that’s the wrong question to ask. It’s not “why not,” but “why so”? It’s so easy to add the conformance, and any type can opt into it so easily, what is the gain by forcing it and can it be justified as a source-breaking change?</div></div></blockquote></div><div class=""><br class=""></div><div class="">You're right that source-breaking changes need to be justified. What I would say is:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>1. This proposal as written will require many conditional conformances; it would be better (and would allow us to fully implement it sooner) if they were unconditional.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>2. Relying on `where` clauses does not help you in type-erased code. `AnyIndex` cannot conditionally conform to `Hashable` because it erases types, and it's not clear to me whether `AnyIndex` can be cleanly converted to `AnyHashable` or vice versa. This means code using type erasure may be awkward to write if it needs `Hashable` indices.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>3. The `KeyPath` case discussed in this proposal is another example where ad-hoc `Hashable` indices cause trouble for type erasure (in that `KeyPath`s erase the types of the indices inside them). It would be very weird for `KeyPath`s to only support indices if they happen to also be `Hashable`.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>4. `Hashable` conformance is extremely useful in general. It allows, among other features, use as a `Set` or `Dictionary` key, and apparently now use in `KeyPath` as well. Replacing an `Array` of indices with a `Set`, or switching from some other representation to a `KeyPath`, is the sort of change we would like generic algorithms to be able to make without breaking binary compatibility with their callers.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>5. `Hashable` occupies a special place of importance among our standard protocols. In the past, we've occasionally discussed making it mandatory and impossible to opt out of; many languages actually do that. Even though we haven't, I've seen experts make flat statements along the lines of "All value types should conform to `Hashable`". This is not like requiring an index to be, say, `Strideable` or a `SignedInteger`.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>6. The compiler can now automatically synthesize `Hashable` conformance for many simple types; this makes the burden of requiring a conformance unusually low.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>7. I have written several custom collections, and it has never occurred to me to conform the index to `Hashable`, but now that it's been mentioned I realize that it would have been both easy and extremely useful to do so. My index types would already have been `Hashable` if the standard library had forced me to do so.</div><div class=""><br class=""></div><div class="">Basically, what it comes down to is, `Hashable` is very useful and there are not many plausible index designs which would have trouble supporting it. It is not absolutely necessary to make this change, but I think it would lead to better, more useful types with a fairly low burden.</div><div class=""><br class=""></div><div class="">
<span class="Apple-style-span" style="border-collapse: separate; font-variant-ligatures: normal; font-variant-east-asian: normal; font-variant-position: normal; line-height: normal; border-spacing: 0px;"><div class=""><div style="font-size: 12px; " class="">-- </div><div style="font-size: 12px; " class="">Brent Royal-Gordon</div><div style="font-size: 12px; " class="">Architechies</div></div></span>
</div>
<br class=""></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></div></div></div></body></html>