On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> > On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote: > > On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris <daveswee...@mac.com> > wrote: > >> >> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote: >> >> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution < >> swift-evolution@swift.org> wrote: >> >>> >>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution < >>> swift-evolution@swift.org> wrote: >>> >>> I think that is perfectly reasonable, but then it seems weird to be able >>> to iterate over it (with no upper bound) independently of a collection). It >>> would surprise me if >>> ``` >>> for x in arr[arr.startIndex…] { print(x) } >>> ``` >>> yielded different results than >>> ``` >>> for i in arr.startIndex… { print(arr[i]) } // CRASH >>> ``` >>> which it does under this model. >>> >>> >>> (I *think* this how it works... semantically, anyway) Since the upper >>> bound isn't specified, it's inferred from the context. >>> >>> In the first case, the context is as an index into an array, so the >>> upper bound is inferred to be the last valid index. >>> >>> In the second case, there is no context, so it goes to Int.max. Then, >>> *after* the "wrong" context has been established, you try to index an >>> array with numbers from the too-large range. >>> >>> Semantically speaking, they're pretty different operations. Why is it >>> surprising that they have different results? >>> >> >> I must say, I was originally rather fond of `0...` as a spelling, but >> IMO, Jaden and others have pointed out a real semantic issue. >> >> A range is, to put it simply, the "stuff" between two end points. A >> "range with no upper bound" _has to be_ one that continues forever. The >> upper bound _must_ be infinity. >> >> >> Depends… Swift doesn’t allow partial initializations, and neither the >> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. >> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist >> without getting into undefined behavior territory. >> >> Plus, mathematically speaking, an infinite range would be written "[x, >> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed* >> upper bracket, that’s kind of a meaningless statement. I would argue that >> if we’re going to represent that “infinite” range, the closest Swift >> spelling would be “x..<“. That leaves the mathematically undefined notation >> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” >> (which by similar reasoning can’t mean "(∞, x]”) return one of these: >> >> enum IncompleteRange<T> { >> case upperValue(T) >> case lowerValue(T) >> } >> >> which we could then pass to the subscript function of a collection to >> create the actual Range like this: >> >> extension Collection { >> subscript(_ ir: IncompleteRange<Index>) -> SubSequence { >> switch ir { >> case .lowerValue(let lower): return self[lower ..< self.endIndex] >> case .upperValue(let upper): return self[self.startIndex ..< >> upper] >> } >> } >> } >> >> > I understand that you can do this from a technical perspective. But I'm > arguing it's devoid of semantics. That is, it's a spelling to dress up a > number. > > > It’s not any more devoid of semantics than a partially applied function. > Yes, but this here is not a partially applied type. Nor does it square with your proposal that you should be able to use `for i in 0...` to mean something different from `array[0...]`. We don't have partially applied functions doubling as function calls with default arguments. > It is a number or index with added semantics that it provides a lower (or > upper) bound on the possible value specified by its type. > > > What is such an `IncompleteRange<T>` other than a value of type T? It's > not an upper bound or lower bound of anything until it's used to index a > collection. Why have a new type (IncompleteRange<T>), a new set of > operators (prefix and postfix range operators), and these muddied semantics > for something that can be written `subscript(upTo upperBound: Index) -> > SubSequence { ... }`? _That_ has unmistakable semantics and requires no new > syntax. > > > Arguing that it adds too much complexity relative to the value it provides > is reasonable. The value in this use case is mostly syntactic sugar so > it’s relatively easy to make the case that it doesn’t cary its weight here. > > The value in Ben’s use case is a more composable alternative to > `enumerated`. I find this to be a reasonably compelling example of the > kind of thing a partial range might enable. > Ben's use case is not a "partial range." It's a bona fide range with no upper bound. > I also tend to find concise notation important for clarity as long as it > isn’t obscure or idiosyncratic. With that in mind, I think I lean in favor > of `…` so long as we’re confident we won’t regret it if / when we take up > variadic generics and / or tuple unpacking. > > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution