<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="">This is an idea I had while working with collections, and is particularly inspired by those that use common index types.<div class=""><br class=""></div><div class="">Consider for example an array; for indices it simply uses an integer, however, while this is a perfectly valid type to use it opens up the possibility of integers from any number of different sources being passed in by mistake and causing run-time errors. The same is true for wrapping types that use AnyIndex, or really any type that uses Any* to hide underlying types, as on the surface all AnyIndex instances give the illusion of being compatible when they're not, and will only produce errors at run-time when a conflict arises.</div><div class=""><br class=""></div><div class="">The idea to combat this is simple; a new attribute that can be applied to a typealias, my working name is @unique, but there's probably a much better name for it. When applied to a type-alias it indicates to the type-checker that the type being aliased should be treated as a unique type outside of the scope in which it is declared.</div><div class=""><br class=""></div><div class="">For example:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>struct MyCollection<T> : Collection {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>@unique typealias Index = Int</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>var startIndex:Index { return 0 }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>…</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div class=""><font face="Monaco" class=""><br class=""></font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var foo = MyCollection<Foo>()</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var bar = MyCollection<Bar>()</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo[bar.startIndex] // warning: incompatible types</font></div><div class=""><br class=""></div><div class="">Although the underlying type is an Int for both collections, and Ints can be used internally to satisfy methods/properties of type Index (i.e- within MyCollection the concrete type is still Int), externally indices are treated as a unique type of MyCollection<T>.Index, that just happens to have all the same methods, operators and properties as Int, minimising the risk of passing an index from the wrong source.</div><div class=""><br class=""></div><div class="">If you actually <b class="">want</b> to pass the "wrong" type you can still do it by casting:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo[bar.startIndex as MyCollection<Foo>.Index]</font></div><div class=""><br class=""></div><div class="">Bit verbose, but it makes absolutely clear that you <b class="">want</b> this to happen, rather than it happening by mistake. The same can also be done in reverse (to change an index to an Int).</div><div class=""><br class=""></div><div class="">Of course this isn't completely fool-proof, as two different instances of MyCollection<Foo> could still confuse indices as they're of the same pseudo-type, but in other cases it reduces the possibility of a mistake. It was the recent discussion on the .enumerate() method that reminded me of this, as a common mistake is to think that the offsets produced by enumerate are indices, just because they happen to be compatible with an Array, this could eliminate that as a mistake by forcing developers to see what's actually happening.</div><div class=""><br class=""></div><div class="">Currently to do something like this requires duplicating types, or using wrappers around Int just to make it appear to be different; it's not hard as such but there's no standard for it, so making it easier and more prevalent is desirable.</div><div class=""><br class=""></div><div class="">This shouldn't have any implications to ABI compatibility as it's a type-checker only feature (the code should still compile exactly as the same is now), but it's a partially source-breaking change in that if Array etc. are changed to use this feature then any code relying on Array indices being integers will need to add a cast. Since the types are still known to be compatible though a mismatch needn't be an error, a warning should suffice, in which case the change won't actually prevent compilation of existing code.</div></body></html>