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