With a lot of these new features, it helps me greatly to see them in action.
I've built a poor man's version of these incomplete ranges in a Swift Sandbox
here:
http://swiftlang.ng.bluemix.net/#/repl/58925f5d42b65e6dce9a5bea
This implementation suffers greatly from a lack of generic subscripts, and the
type names are terrible and not at all suggestions. Otherwise, as far as I can
tell, the behavior of the one-sided ranges correctly matches what Ben is
describing here — if you're unsure about how this will look and behave in
practice, please take a look.
Nate
> On Feb 1, 2017, at 10:37 AM, Ben Cohen via swift-evolution
> <[email protected]> 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
>> <[email protected] <mailto:[email protected]>> 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 <[email protected]
>> <mailto:[email protected]>> 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
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution