[swift-evolution] [Pre-proposal] Enforcing Correct use of Array Indices

Dave Abrahams dabrahams at apple.com
Fri Sep 30 07:10:58 CDT 2016

on Thu Sep 29 2016, Haravikk <swift-evolution at swift.org> wrote:

> So the issue of Array index safety came up on the discussion for the
> .indexed() proposal. Now of course there's nothing wrong with arrays
> using integers as indices as such, but it does mean that indices can
> be manipulated outside of the array, which somewhat defeats the idea
> of the indexing model requiring them to be passed back to the parent
> collection for manipulation.
> In a few types of my own I've avoided this problem by doing the
> following:
> public struct MyMaskedIndex : Comparable { fileprivate var raw:Int }
> // Comparable conformance omitted
> public struct MyType : Collection {
>     // Lots of stuff omitted
>     public func distance(from start:MyMaskedIndex, to
> end:MyMaskedIndex) -> Int {
>         return end.raw - start.raw;
>     }
> }
> In essence MaskedIndex is still just an Int, and should optimise as
> such, but in development the use of a type like this ensures that
> indices from my collection can't be manipulated externally, which
> enables the type-checker to conveniently prevent any mistakes I might
> make. It's a handy pattern for other things like hashed values,
> ensuring I can't use unhashed values of the same type by accident and
> so-on.

Yeah, but it doesn't really ensure you won't use an invalid index.
Among many other things, you can always reset the collection to an empty
state and all the old indices become invalid with respect to it.

> I just wanted to raise the topic to see what other people thought
> about the idea of doing something similar for Array and any other
> types that use integer types directly as indices? For convenience it
> is still possible to have a public initialiser on the masking type(s),
> so that custom values can be used, but by using MaskedIndex(raw:) it
> should be much more obvious what's happening.

Believe me, we considered this when doing the Array design.  Being able
to index an Array with Ints is pretty fundamental to its usability and
adoptability, and wrapping the index doesn't buy any real safety.


More information about the swift-evolution mailing list