A bit late, but I agree with Ben on all of this. We could have separate 
IncompleteRange and InfiniteRange types, and have a consistent world, and even 
figure out how to get the context-less case to pick InfiniteRange. But we don’t 
have to, and I don’t think it buys us anything because—as was said—the two 
kinds of ranges are never used in the same context. There’s no overload madness.

On the specific point that `for i in 0…` behaves differently than `for elem in 
arr[0…]`, I think that’s just picking one interpretation of “arr[0…]” and then 
(legitimately) claiming it leads to nonsense. I see no problem saying that a 
subscript for an IncompleteRange, or LowerBoundedRange, or whatever gives you 
the elements starting at that index, but that trying to iterate such a range 
(when Countable) gives you unlimited iteration. I think this is more a 
theoretical concern than a practical one.

Jordan


> On Feb 1, 2017, at 10:37, Ben Cohen via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
> I think Dave has already made these points separately but it probably helps 
> to recap more explicitly the behavior we expect from “x…"
> 
> Names are just for discussion purposes, exact naming can be left as a 
> separate discussion from functionality:
> 
> - Informally, one-sided ranges are a thing. Formally, there are lower-bounded 
> one-sided ranges, which are created with a postfix ... operator. For now, 
> let’s just fully understand them and come back to upper-bounded ranges later.
> - Collections will have a subscript that takes a one-sided range and returns 
> a SubSequence. The behavior of that subscript is that the collection "fills 
> in" the “missing” side with it’s upper/lower bound and uses that two-sided 
> range to return a slice.*
> - When the Bound type of a lower-bounded range is countable, it will conform 
> to Sequence.** The behavior of that sequence’s iterator is that it starts at 
> the lower bound, and increments indefinitely.
> - One-sided ranges should have ~= defined for use with switch statements, 
> where any value above the bound for a lower-bounded range would return true.
> 
> * implementation detail: collections would probably have a generic subscript 
> taking a type conforming to RangeExpression, and that protocol would have a 
> helper extension for filling in the missing range given a collection
> **one-sided ranges ought in fact to be infinite Collections… a concept that 
> needs a separate thread
> 
> With that defined:
> 
>> On Feb 1, 2017, at 5:02 AM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I entirely agree with you on the desired behavior of `zip(...)`.
>> 
>> However, if you insist on 0... being notionally an infinite range, then you 
>> would have to insist on `for i in 0...` also trapping. Which is not a big 
>> deal, IMO, but will surely make the anti-trapping crowd upset.
>> 
> 
> Certainly, for i in 0… would trap once the iterator needs to increment past 
> Int.max. If you break out of the loop before this happens, it won’t trap. The 
> statement is the moral equivalent of a C-style for(i = 0; /*nothing*/ ; ++i).
> 
> If the anti-trapping crowd are upset, they should be upset with Int, not this 
> range type. The range has no opinion on trapping – its iterator just 
> increments its Bounds type when asked to.
> 
>> The bigger issue is that either you must have a lenient/clamping subscript 
>> for `arr[0...]` or it too must trap, which is not desired. 
> 
> Based on the definition I give above, arr[0…] means “from 0 up to the 
> endIndex of arr”. This will not trap.
> 
> (there is a legitimate quibble here that this will translate into 
> arr[0..<arr.endIndex], but the … kind of implies arr[0…arr.endIndex] which is 
> invalid. But 0..< is ugly so we should ignore this quibble for the sake of 
> aesthetics)
> 
>> However, if `arr[0...]` is clamping, then `[1, 2, 3][100...]` would not trap 
>> and instead give you `[]`.
>> 
> 
> It should trap, because 100..<arr.endIndex is not a valid argument for 
> slicing this array.
> 
>> If 0... is regarded as an incomplete range, your example of `zip(...)` could 
>> still trap as desired. It would trap on the notional attempt to assign 
>> someArray.count to IncompleteRange<T>.inferredUpperBound if count exceeds 
>> T.max. 
> 
> It’s unclear to me whether you are trying to formally define 
> .inferredUpperBound as a property you expect to exist, or if you’re using it 
> as informal shorthand. But there is no implied upper bound to a one-sided 
> lower-bounded range, only an actual lower bound. Operations taking 
> lower-bounded ranges as arguments can infer their own upper bound from 
> context, or not, depending on the functionality they need.
> 
> As an example of an alternative inferred upper bound: suppose you want to 
> define your own ordering for ranges, for sorting/display purposes. You decide 
> on a lexicographic ordering first by lower then upper bound. You want 
> one-sided ranges to fit into this ordering. So you infer the upper bound to 
> be infinite, for sorting purposes, so: 0…5 < 0… < 1…4 < 1…5 < 1…. This does 
> not mean the upper bound is implied to be infinite, just that the sorting 
> predicate infers it to be, for the purpose of sorting.
> 
>> With such semantics for 0..., [1, 2, 3][0...] would behave as expected 
>> without the need for leniency, but [1, 2, 3][100...] would trap as I assume 
>> you'd expect. 
> 
> [1,2,3][0…] is valid because the array has an index of 0, but [100…] isn’t 
> because it doesn’t.
> 
> It’s worth noting the difference with Python here. In Python, [][2:] is valid 
> because [][2:n] is valid (both return []). In Swift, [][2…] should be invalid 
> (trap) because [][2..<n] is invalid.
> 
>> However, it would make no sense to write `for i in 0...`.
>> 
> 
> I don’t see how. But regardless, the definition of how countable 
> lower-bounded ranges conform to Sequence is just something to be defined in 
> some way that is useful and intuitive to users. 0… being an indefinitely 
> increasing sequence seems like it’s intuitive to me, as does a[n…] being “a 
> slice from n to the end”.
> 
> That definition does not need to be unearthed based on some underlying 
> principles. Defining behavior based on building upon axioms is a useful 
> approach sometimes, but if at any point we are finding they get in the way of 
> implementations within the std lib being intuitive or useful, we should stop 
> trying to bend over backwards to stick with this approach.
> 
> 
>> On Tue, Jan 31, 2017 at 21:39 Dave Abrahams <dabrah...@apple.com 
>> <mailto:dabrah...@apple.com>> wrote:
>> 
>> on Tue Jan 31 2017, Xiaodi Wu <xiaodi.wu-AT-gmail.com 
>> <http://xiaodi.wu-at-gmail.com/>> wrote:
>> 
>> > But that's not getting to the biggest hitch with your proposal. If
>> > subscript were lenient, then `arr[lenient: 42...]` would also have to give
>> > you a result even if `arr.count == 21`.
>> >
>> > This is not at all what Dave Abrahams was proposing, though (unless I
>> > totally misunderstand). He truly doesn't want an infinite range. He wants
>> > to use a terser notation for saying: I want x to be the lower bound of a
>> > range for which I don't yet know (or haven't bothered to find out) the
>> > finite upper bound. It would be plainly clear, if spelled as `arr[from:
>> > 42]`, that if `arr.count < 43` then this expression will trap, but if
>> > `arr.count >= 43` then this expression will give you the rest of the
>> > elements.
>> 
>> I think you do misunderstand.  Notionally, 0... is an infinite range.
>> The basic programming model for numbers in swift is (to a first
>> approximation), program as if there's no overflow, and we'll catch you
>> by trapping if your assumption is wrong.  It doesn't make sense for the
>> semantics of 0... to depend on the deduced type of 0 or the
>> representable range of Int
>> 
>> for example,
>> 
>>     for x in zip(n..., someArray) {
>> 
>>     }
>> 
>> How many iterations should this give you?  If it doesn't process all of
>> someArray, I want a trap.
>> 
>> --
>> -Dave
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to