[swift-evolution] [Pitch] Adding safety to arrays

Karl Wagner razielim at gmail.com
Mon Apr 17 13:03:10 CDT 2017


> On 17 Apr 2017, at 18:35, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> on Fri Apr 14 2017, Karl Wagner <swift-evolution at swift.org> wrote:
> 
>> Personally, the only valid use-case I can think of is when you want to
>> initialise an Array’s elements out-of-order - i.e., you want to set a
>> value for myArray[2] despite myArray[0] and [1] not being
>> populated. In that case, it would be better to have some kind of
>> SparseArray type, and for us to have a proper API for unsafe
>> initialisation of stdlib types.
> 
> That is a point in the design space, but there's really no need to
> expose unsafe initialization in order to get that functionality.  You
> could simply build ArrayOfOptional<T> that would present the same API as
> Array<T?> but would use a separate inline buffer of bits to denote which
> of the optionals were non-nil.
> 
> -- 
> -Dave
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

I wasn’t saying a SparseArray type should be part of the standard library, but possibly it’s something which could be added to Foundation or some 3rd-party “Common Collections” package.

Like all data structures, the most efficient one depends on how well you can predict what it will store and how it will be accessed/modified. A Dictionary<Integer> might be great for large collections that are exceptionally sparse, but it may also be wasteful depending on your circumstance.

As for unsafe initialisation, that’s something I badly, badly want. Basically, I want to be able to tell Array or String to allocate an internal buffer of size N, then fill it myself (perhaps using POSIX functions like read or recv, or concurrently with no guaranteed order), and tell it how much data I actually initialised. Then you could stroll off in to the sunshine with a real Array<T> or String that you read from a file or socket without copying. That’s the point when Array becomes as good as a C Array for me.

Of course, String being UTF16 would be an issue. There aren’t many files stored in UTF16, and even for sockets, if the server isn’t also Swift, you’ll probably be getting fed UTF8. You will still need to copy as you read in to a buffer of UTF8 before initialising the String’s backing storage with the corresponding UTF16 code-units. Perhaps the new String model/unicode encodings can help make that easier in some way.

Still, unsafe initialisation would be totally badass; In Objective-C, NSString needs to have a special method to read its data from a file to handle that one particular use-case, so it can use private knowledge to more efficiently read the file directly in to an internal buffer (I presume…). The alternative is to read the bytes in as an NSData and copy them in to an NSString (before throwing the NSData away, most likely). In Swift, we can have a better, more generalised solution.

- Karl



More information about the swift-evolution mailing list