[swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol<P1, P2> syntax with Any<P1, P2>
Austin Zheng
austinzheng at gmail.com
Wed Jun 8 17:29:09 CDT 2016
(inline)
On Wed, Jun 8, 2016 at 3:18 PM, Dave Abrahams <dabrahams at apple.com> wrote:
>
> on Wed Jun 08 2016, Austin Zheng <austinzheng-AT-gmail.com> wrote:
>
> > We might be talking past each other. I think Matthew is talking about
> using
> > an existential outside the context of generic functions. For example,
> > something like this should be trap-proof (as long as 'x' is immutable,
> > which it is in this example):
>
> [Ugh, Austin, your mail program is stripping the tabs out of the
> plaintext part so the indendation is lost. Grabbing from browser...]
>
Sorry! I'm using gmail in the browser. I'll stay away from tabs...
>
> > func copySequenceIntoArray(x: Any<Sequence where .Iterator.Element ==
> Int>) -> [Int] {
> > var buffer : [Int] = []
> > // Stupid implementation to make a point
> > var iterator : x.Iterator = x.makeIterator()
> > while true {
> > let nextItem : Int? = iterator.next()
> > if let nextItem = nextItem {
> > buffer.append(nextItem)
> > } else {
> > return buffer
> > }
> > }
> > }
>
> Presumably this would “work” as well?
>
> typealias IntSequence = Any<Sequence where .Iterator.Element == Int>
> func f(x: IntSequence, y: IntSequence) {
> var i = x.makeIterator()
> i = y.makeIterator() // <== NO TRAP HERE, EVER.
> }
>
This presumably wouldn't compile. The sort-of-dependent-type "x.Iterator"
(return value of x.makeIterator(); inferred as type of 'i'), and
"y.Iterator" (return type of y.makeIterator()) would not be considered
equivalent.
(As Doug mentioned in a recent email, it would only be feasible to expose
such types on immutable values. The intention is not to allow the
largely-meaningless code that follows:
func f(x: IntSequence, y: IntSequence) {
var z : IntSequence = x
var something : z.Iterator = x.makeIterator()
z = y
something = y.makeIterator()
// ...
}
)
>
> > Even this would never trap as well:
> >
> > func copySequenceIntoArray<T>(x: Any<Sequence where .Iterator.Element ==
> T>) -> [T] {
> > var buffer : [T] = []
> > for item in x {
> > buffer.append(item)
> > }
> > return buffer
> > }
>
> Sure, this one is simple because the associated type is never even
> exposed.
>
> > Where we run into difficulty is something like this (forgive my abuse
> > of the collections API; I don't remember all the new indexing APIs off
> > the top of my head):
> >
> > func doSomething<T : Collection where T.Element == Int>(x: T, y: T) {
> > // Get indexes out of x and use them to index into y
> > var idx = x.startIndex
> > while (idx != x.endIndex || idx != y.endIndex) {
> > print(x[idx])
> > print(y[idx])
> > idx = x.nextIndex(idx)
> > }
> > }
> > let someSeq : Any<Collection where .Element == Int> = // ...
> > let anotherSeq : Any<Collection where .Element == Int> = // ...
> > // Trouble!
> > // someSeq and anotherSeq are the same existential type
> > // But the concrete index types within each of the existential variables
> may be different
> > doSomething(someSeq, anotherSeq)
> >
> > may be different
> > doSomething(someSeq, anotherSeq)
> >
> > It's this situation (using an existential type to fulfill a generic
> > type parameter constrained to the same requirements that comprise that
> > existential) that requires either of the two options that Dave
> > presented, due to our lack of compile-time type information about the
> > fulfilling type's associated types.
>
> Exactly. But much simpler cases will also either have to trap at
> runtime or be prohibited outright:
>
Of course. I don't know what the right solution to this is yet.
>
> func subscript_<C: Collection>(c: C, i: C.Index) -> C.Collection.Element
> {
> return c[i]
> }
>
> typealias IntCollection = Any<Collection where Element == Int>
> let c1: IntCollection = ...
> let c2: IntCollection = c1[3..<10]
> let c3: IntCollection = ...
> let c4: IntCollection = c1.reversed()
>
> // Note: the underlying index types are the same, and are supposed to
> // interoperate. What do you do (work/trap/nocompile)?
> _ = subscript_(c1, c2.startIndex)
>
> // The underlying index types happen to be the same, and are not
> // supposed to interoperate. What do you do (silently
> “work”/trap/nocompile)?
> _ = subscript_(c1, c3.startIndex)
>
> // The underlying index types are different. What do you do
> (trap/nocompile)?
> _ = subscript_(c1, c4.startIndex)
>
> --
> Dave
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160608/97a02c86/attachment.html>
More information about the swift-evolution
mailing list