Proposal to change subscript value type on Array and other collection types.


#1

Hi,

My first post to this list so apologies if its not in the correct format or irrelevant / wrong :slight_smile: Its quite simple, so i'm under the impression that perhaps there is already a very good reason why the below behaviour is on purpose, if this is the case i'd love to learn why, so view it as a proposal / question.

When accessing Array's in Swift (and potentially other types) a Int (signed) is expected, as Array can't have a negative bounds in Swift (as far as i'm aware) would it be sensible to make these UInt? therefor removing the need for tests etc and guarding around negative integers?

For Example:

聽聽聽聽聽聽let someArray = ["a", "b", "c"]
聽聽聽聽聽聽print(someArray.count.dynamicType) // Int

聽聽聽聽聽聽let someIndex = 1
聽聽聽聽聽聽print(someArray[someIndex]) // b

聽聽聽聽聽聽let anotherIndex : UInt = 1
聽聽聽聽聽聽print(someArray[anotherIndex]) // cannot subscript a value of type '[String]' with an index of type 'UInt'

聽聽聽聽聽聽let invalidIndex = -1
聽聽聽聽聽聽print(someArray[invalidIndex]) // Darwin: EXC_BAD_INSTRUCTION / Linux REPL: Error running code: unknown error code 132.

聽聽聽聽聽聽print (invalidIndex.dynamicType) // Int

聽聽聽聽聽聽If Array took a UInt, the line 'print(someArray[invalidIndex])' would fail at COMPILE time rather than RUNTIME.

Looking at the Swift source there are things like

聽聽聽聽聽_sanityCheck(count >= 0)

Which would be unnecessary if using the type system with UInt.

I'm aware that almost everyone bounds checks Array's before access etc, however is there a reason someone can explain for not using a 'UInt' in these circumstances for 'Array' and other collection types.

Thanks,

Michael


(Donnacha Ois铆n Kidney) #2

There鈥檚 a good discussion of this here <https://devforums.apple.com/thread/263668>.

路路路

On 17 Dec 2015, at 16:55, Michael Armstrong via swift-evolution <swift-evolution@swift.org> wrote:

Hi,

My first post to this list so apologies if its not in the correct format or irrelevant / wrong :slight_smile: Its quite simple, so i'm under the impression that perhaps there is already a very good reason why the below behaviour is on purpose, if this is the case i'd love to learn why, so view it as a proposal / question.

When accessing Array's in Swift (and potentially other types) a Int (signed) is expected, as Array can't have a negative bounds in Swift (as far as i'm aware) would it be sensible to make these UInt? therefor removing the need for tests etc and guarding around negative integers?

For Example:

聽聽聽聽let someArray = ["a", "b", "c"]
聽聽聽聽print(someArray.count.dynamicType) // Int

聽聽聽聽let someIndex = 1
聽聽聽聽print(someArray[someIndex]) // b

聽聽聽聽let anotherIndex : UInt = 1
聽聽聽聽print(someArray[anotherIndex]) // cannot subscript a value of type '[String]' with an index of type 'UInt'

聽聽聽聽let invalidIndex = -1
聽聽聽聽print(someArray[invalidIndex]) // Darwin: EXC_BAD_INSTRUCTION / Linux REPL: Error running code: unknown error code 132.

聽聽聽聽print (invalidIndex.dynamicType) // Int

聽聽聽聽If Array took a UInt, the line 'print(someArray[invalidIndex])' would fail at COMPILE time rather than RUNTIME.

Looking at the Swift source there are things like

聽聽聽_sanityCheck(count >= 0)

Which would be unnecessary if using the type system with UInt.

I'm aware that almost everyone bounds checks Array's before access etc, however is there a reason someone can explain for not using a 'UInt' in these circumstances for 'Array' and other collection types.

Thanks,

Michael
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(ilya) #3

would it be sensible to make these UInt?

It's really nice to have one Int type to rule over all integers. This means
that a reasonable program can be written without casting.

Which would be unnecessary if using the type system with UInt.

No, if subsript required UInt everyone would simply insert a cast, and -1
would still create problems as UInt.max.

路路路

On Thu, Dec 17, 2015 at 7:55 PM, Michael Armstrong via swift-evolution < swift-evolution@swift.org> wrote:

Hi,

My first post to this list so apologies if its not in the correct format
or irrelevant / wrong :slight_smile: Its quite simple, so i'm under the impression that
perhaps there is already a very good reason why the below behaviour is on
purpose, if this is the case i'd love to learn why, so view it as a
proposal / question.

When accessing Array's in Swift (and potentially other types) a Int
(signed) is expected, as Array can't have a negative bounds in Swift (as
far as i'm aware) would it be sensible to make these UInt? therefor
removing the need for tests etc and guarding around negative integers?

For Example:

聽聽聽聽聽let someArray = ["a", "b", "c"]
聽聽聽聽聽print(someArray.count.dynamicType) // Int

聽聽聽聽聽let someIndex = 1
聽聽聽聽聽print(someArray[someIndex]) // b

聽聽聽聽聽let anotherIndex : UInt = 1
聽聽聽聽聽print(someArray[anotherIndex]) // cannot subscript a value of type
'[String]' with an index of type 'UInt'

聽聽聽聽聽let invalidIndex = -1
聽聽聽聽聽print(someArray[invalidIndex]) // Darwin: EXC_BAD_INSTRUCTION /
Linux REPL: Error running code: unknown error code 132.

聽聽聽聽聽print (invalidIndex.dynamicType) // Int

聽聽聽聽聽If Array took a UInt, the line 'print(someArray[invalidIndex])' would
fail at COMPILE time rather than RUNTIME.

Looking at the Swift source there are things like

聽聽聽聽_sanityCheck(count >= 0)

Which would be unnecessary if using the type system with UInt.

I'm aware that almost everyone bounds checks Array's before access etc,
however is there a reason someone can explain for not using a 'UInt' in
these circumstances for 'Array' and other collection types.

Thanks,

Michael
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution