[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