> On Feb 2, 2017, at 2:19 PM, Dave Abrahams <[email protected]> wrote:
>
>
> on Thu Feb 02 2017, Jonathan Hull <jhull-AT-gbis.com> wrote:
>
>> Just out of curiosity, what are the use-cases for an infinite sequence
>> (as opposed to a sequence which is bounded to the type’s representable
>> values)?
>
> 1. The type may not have an inherent expressible bound (see BigInt,
> UnsafePointer, and *many* real-life Index types).
If I understand what you are saying, this is why I was arguing that these
partial ranges should not, by themselves, conform to Sequence. In cases where
you do have a natural expressible bound, then it should conditionally conform
to sequence. In other cases, you should have to write that conformance
yourself if you want it.
>
> 2. I keep repeating variants of this example:
>
> func listElements<
> S: Sequence, N: Number
>> (of s: S, numberedFrom start: N) {
> for (n, e) in zip(start..., s) {
> print("\(n). \(e)")
> }
> }
>
> which avoids incorrect behavior when N turns out to be a type that
> can't represent values high enough to list everything in s—**if and
> only if** `start...` is an unbounded range, rather than one that
> implicitly gets its upper bound from its type.
I really worry about the possibility of long-term foot-gunning in this case. I
showed this to a friend who maintains old/abandoned codebases for a living, and
he said “Oh god, that isn’t going to actually crash until 5 years in, when it
gets passed some rare type of file… and by then the original programmer will
have left.” He hit on exactly what I had been feeling as well (but hadn’t been
able to put into words until I heard his). The thought is that this will help
the programmer find an error by trapping, but because it is dependent on the
interactions of two subsystems, it will often create one of those crashes where
the stars have to align for it to happen (which are my least favorite type of
bug/crash to debug).
I think this example also shows how my suggestion of requiring an extra
protocol for conformance to Sequence would actually be much more effective in
preventing the programmer error…
You would not have been able to write the function the way you did, because
writing ‘start…’ as a sequence would have required the addition of ‘where
N:FiniteComparable’ (or whatever we call the protocol providing natural
bounds). In having to write that N needs bounds, you are much more likely to
be thinking of what those bounds might be. The problem here is really with the
design of the listElements function in allowing/encouraging that error, as
opposed to the caller... and the trap is more likely to make you look at the
call site because of the context of when it happens. Having to write the
‘where’ statement makes you reconsider the design of the function, again
because of the context of when it happens.
Thanks,
Jon
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution