<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="">What about .count? Is it possible for that to be negative? <i class="">If</i> we change how count is represented, I think it should be switched to size_t, rather that UInt. I’m aware that they’re currently the same thing, but that might not always be the case, and, at least the way I understand things, the max value of a platform’s “pointer” type is more directly tied to the maximum possible element count than the max value of its native uint type. I know of at least one platform in development which uses 64 bits for pointers, but the address space is only 61 bits because the CPU & memory system use 3 bits for flags.<div class=""><br class=""></div><div class="">- Dave Sweeris<br class=""><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 3, 2016, at 11:58, David Turnbull via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">-1 CollectionType and it's ilk, contrary to what you believe, were designed to handle negative indexes just fine. Or even indexes that aren't numeric. And there's plenty of real use cases for this.<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="color:rgb(187,44,162)" class="">class</span><span style="" class=""> GraphRow : </span>MutableCollectionType<span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">var</span> values = [<span style="color:rgb(112,61,170)" class="">Int</span>](count: <span style="color:rgb(39,42,216)" class="">201</span>, repeatedValue: <span style="color:rgb(39,42,216)" class="">0</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">var</span> startIndex: <span style="color:rgb(112,61,170)" class="">Int</span> { <span style="color:rgb(187,44,162)" class="">return</span> -<span style="color:rgb(39,42,216)" class="">100</span> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">var</span> endIndex: <span style="color:rgb(112,61,170)" class="">Int</span> { <span style="color:rgb(187,44,162)" class="">return</span> <span style="color:rgb(39,42,216)" class="">100</span> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">subscript</span>(column: <span style="color:rgb(112,61,170)" class="">Int</span>) -> <span style="color:rgb(112,61,170)" class="">Int</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">get</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">return</span> <span style="color:rgb(79,129,135)" class="">values</span>[column+<span style="color:rgb(39,42,216)" class="">100</span>]</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(187,44,162)" class="">set</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(79,129,135)" class="">values</span>[column+<span style="color:rgb(39,42,216)" class="">100</span>] = newValue</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="color:rgb(187,44,162)" class="">var</span><span style="" class=""> r = </span>GraphRow<span style="" class="">()</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(79,129,135)" class="">r</span><span style="color:rgb(49,89,93)" class="">[</span>-<span style="color:rgb(39,42,216)" class="">3</span><span style="color:rgb(49,89,93)" class="">]</span> = <span style="color:rgb(39,42,216)" class="">12</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(79,129,135)" class="">r</span><span style="color:rgb(49,89,93)" class="">[</span><span style="color:rgb(39,42,216)" class="">9</span><span style="color:rgb(49,89,93)" class="">]</span> = <span style="color:rgb(39,42,216)" class="">2</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);" class="">print<span style="" class="">(</span><span style="color:rgb(79,129,135)" class="">r</span><span style="color:rgb(49,89,93)" class="">[</span><span style="" class="">-</span><span style="color:rgb(39,42,216)" class="">3</span><span style="color:rgb(49,89,93)" class="">]</span><span style="" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(61,29,129)" class="">print</span>(<span style="color:rgb(79,129,135)" class="">r</span>.<span style="color:rgb(61,29,129)" class="">reduce</span>(<span style="color:rgb(39,42,216)" class="">0</span>, combine: +))</div></div><div class=""><br class=""></div>-david<div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Feb 3, 2016 at 9:31 AM, James Froggatt via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">In the standard library, there are methods (notably array subscripts, CollectionType's .count and the dimensions of CGSize) which are designed to deal only with natural (non-negative) numbers. Functions either throw an error if a parameter is negative, or else ignore the possibility of a negative value finding its way into these functions.<br class="">
<br class="">
By updating the standard library with a natural number type to represent these values (and potentially the Swift interfaces for Foundation and other frameworks), there is no way a negative number can be passed to these functions. This eliminates the need for many preconditions, allowing them to eliminate the possibility of a crash, and it would be clear that values such as count will never be negative.<br class="">
<br class="">
If this change were accepted, the user would have to explicitly convert between the types at some points in their code. This could be seen as a burden, but requiring a cast encourages the programmer to check for negative values, keeping negatives out of natural number functions, and moving checks to the source of the data, similar to how Optionals eliminate nil values early on.<br class="">
<br class="">
The parallel to Optionals is, in my opinion, the most appealing aspect of this idea. With Swift's focus on type safety, the lack of distinction between natural numbers and potentially negative ones seems like an omission, given how commonly both kinds of number are used. Enabling this level of integral safety would add additional clarity and reduce potential errors. Use cases include not just indexes, but in sizes such as collections' count and CG dimensions, for both clarity when getting values, and enforcing valid values at initialisation.<br class="">
<br class="">
UInt is the obvious candidate to represent integer natural numbers, but is hazardous in edge cases: UInt allows an extra bit for magnitude, so has the possibility of overflow when converting back to Int. I assume this hazard is the primary reason UInt currently isn't used. If this a concern, a separate collection of types for natural integers (NInt?) could be created, which could be a strict subset of the correspondingly sized Int values (using n-1 bits).<br class="">
<br class="">
This would mean adding a new collection of integer types in the standard library, which is undesirable. However, for high level applications which Swift is primarily used for, this would arguably be a more useful type than UInt, considering the near absence of UInt in current APIs, and its tiny increase (1 bit?) in precision compared to using an Int of a larger size. An unsigned Integer subset would allow safe conversion back to Int, and the conversion from Int is relatively simple, from the design perspective - ignore the sign bit, throw an error, or round up to 0, as appropriate.<br class="">
<br class="">
Alternatives include:<br class="">
• A generic wrapper for Int which constrains its possible values. This would allow inherent support for use with existing operators, but would be rather clunky in cases where only natural numbers are being dealt with.<br class="">
• In a future version of Swift, the addition of type parameters constraining possible values may enable this to be added, but even if this does get added it may be too late to make such a major change.<br class="">
• Leaving the APIs as they are and require every function dealing with natural numbers to either throw a runtime error when a negative is passed. If the user forgets to follow this rule (or wont put in the extra effort to add the check), their functions will have unspecified behaviour.<br class="">
<br class="">
This ended up longer than I would like, sorry about that. I don't think this issue has been covered here.<br class="">
I'd be interested to hear responses and opinions, and while I'm confident this change would be beneficial if done correctly, doing it correctly is easier said that done.<br class="">
<br class="">
- James<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>