[swift-evolution] [Idea] NonEmptyArray

Charlie Monroe charlie at charliemonroe.net
Tue Jan 17 07:27:14 CST 2017


> On Jan 17, 2017, at 2:14 PM, Haravikk <swift-evolution at haravikk.me> wrote:
> 
> 
>> On 17 Jan 2017, at 09:57, David Sweeris via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> 
>> On Jan 17, 2017, at 03:40, Charlie Monroe via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> I've come across multiple cases, where you simply know the array is never empty and hence the optionality on first, last and behavior of a few other members is slightly different. Also, there are cases where you want to declare that you shouldn't pass an empty array e.g. into an initializer.
>>> 
>>> I was wondering whether Swift could have a specialized NonEmptyArray that could be used throughout the stdlib - e.g. String.components(separatedBy:) would return NonEmptyArray.
>>> 
>>> Thoughts?
>> 
>> I've tried to make such a type a few times... The struct itself isn't hard ("var first:T; var tail:[T]"), but I never could figure out how to make `NonEmptyArray` conform to `ExpressibleByArrayLiteral` (because the protocol doesn't allow for failable inits) without just crashing if there wasn't at least one element.
>> 
>> Anyway, I'm not opposed to adding it, as long as there's a non-crashy way to assign array literals to them.
> 
> Is a failable initialiser the way to go? Could we do something with some kind of compiler attribute?
> 
> For example:
> 
> 	struct MyNonEmptyArray<E> : ExpressibleByArrayLiteral {
> 		typealias Element = E
> 		@minParameters(1) init(arrayLiteral:Element…) { … }
> 	}
> 
> In this case the @minParameters attribute tells the compiler how many parameters must be present in direct calls to this method, however, for cases where this isn't possible to check it would still trigger a runtime error, but that would only be for more unusual cases like trying to handle this type as a generic ExpressibleByArrayLiteral.

I personally agree that I wouldn't make it failable. The compiler should be able to detect making of a NonEmptyArray with 0 literals and there's nothing against marking an empty initializer as @available(*, unavailable) - it will conform to the necessary protocols, but you won't be able to invoke it.

> Just trying to think whether there might be a more flexible way to do this, as if you can support arrays with at least 1 element, then why not 2 or 3 etc.? In the worst case this would just become a runtime error, which is how we would have to handle right now, but in more common cases the compiler can give an error right away.

I have thought about this, but to be honest, even math-wise, an empty set (or array) is a special case... So I began wondering whether it would make sense to add something that explicitely states that the array is not empty. If I'm not mistaken, since it would change the return type of a few stdlib methods, the time to discuss it would be now...

It's true that you can handle this with assertions, as I've noted, was just wondering if there's a better way...


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170117/6db621c6/attachment.html>


More information about the swift-evolution mailing list