[swift-evolution] [Pitch] Remove type inference for associated types

Douglas Gregor dgregor at apple.com
Wed Jun 29 10:51:05 CDT 2016


The detailed design section of 

  https://github.com/apple/swift-evolution/blob/master/proposals/0108-remove-assoctype-inference.md

Now talks about this. It's not a new problem, and I'm firstly confident that the near-miss checking approach will address the issues.

Sent from my iPhone

> On Jun 29, 2016, at 8:16 AM, Brandon Knope <bknope at me.com> wrote:
> 
> This is true! Swift is suppose to be a safe language that can prevent these kind of pitfalls. 
> 
> But I feel there was a rationale for having the way it is...I just don't know it
> 
> Brandon 
> 
>> On Jun 29, 2016, at 10:21 AM, Sean Heber <sean at fifthace.com> wrote:
>> 
>> Another issue here (perhaps) is, what if you misspelled the associated type when you attempted to typealias it manually? Would it not just make a new typealias with your misspelled name and then, potentially, you’d get an error or would something end up working but in unexpected ways? Would the typo be easy to identify if you had a lot of typealiases or associatedtypes or typos?
>> 
>>   protocol P {
>>     associatedtype Index = Int
>>   }
>> 
>>   struct X : P {
>>     typealias index = String  // whoops - no capital I - how long does this bug take to find? :P
>>   }
>> 
>> There will always be bugs, of course. Maybe this isn’t a significant concern?
>> 
>> l8r
>> Sean
>> 
>> 
>> 
>>> On Jun 29, 2016, at 8:55 AM, Brandon Knope via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> What's the rationale for having associatedtype in protocols and typealias in the conforming types?
>>> 
>>> This has actually been a point of confusion for me as it seems inconsistent 
>>> 
>>> Brandon
>>> 
>>> Sent from my iPad
>>> 
>>>> On Jun 29, 2016, at 1:33 AM, Douglas Gregor via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> 
>>>>> On Jun 24, 2016, at 10:50 PM, Austin Zheng via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> Hello all,
>>>>> 
>>>>> Per Chris Lattner's list of open Swift 3 design topics (http://article.gmane.org/gmane.comp.lang.swift.evolution/21369), I've put together a proposal for removing type inference for associated types.
>>>>> 
>>>>> It can be found here: https://github.com/austinzheng/swift-evolution/blob/az-assoctypeinf/proposals/XXXX-remove-assoctype-inference.md
>>>>> 
>>>>> Thoughts, criticism, and feedback welcome. There are at least two slightly different designs in the proposal, and I'm sure people will have ideas for even more.
>>>> 
>>>> Thanks for working on this. I have a couple of comments.
>>>> 
>>>> I don’t think we should be adding the ability to write ‘associatedtype’ declarations in classes/structs/enums. We already have the ability to explicitly state the associated type witness by declaring a typealias, struct, enum, or class with the appropriate name. Indeed, I feel like a lot of complexity of the proposal is linked to adding  ‘associatedtype’ declarations into the language, and I’d rather this proposal stay narrow.
>>>> 
>>>> I think it’s important for this proposal to show the other ways in which one can get associated type witnesses without writing them explicitly in the conforming type, even once inference goes away. For example, we have associated type defaults, e.g.,
>>>> 
>>>>   protocol P {
>>>>     associatedtype Associated = Int
>>>>   }
>>>> 
>>>>   struct X : P {
>>>>     // Associated becomes Int if not otherwise specified
>>>>   }
>>>> 
>>>> and with typealiases in protocol extensions becoming real and useful, one could also use protocol extensions:
>>>> 
>>>>   protocol P2 {
>>>>     associatedtype Index
>>>>   }
>>>> 
>>>>   extension P2 {
>>>>     typealias Index = Int
>>>>   }
>>>> 
>>>> which, of course, implies that one can use various tricks with constrained protocol extensions and such. There isn’t any proposed change here, but it illustrates that Swift programmers aren’t without recourse if type inference for associated types go away.
>>>> 
>>>> One concern with applying the above tricks is that existing code can change meaning when inference goes away. For example, let’s think about the “Iterator” type of a Sequence. It already uses default associated type witnesses (not associated type witness inference!) to give a default of IndexingIterator<Self>, e.g.,
>>>> 
>>>>   protocol Sequence {
>>>>     associatedtype Iterator: IteratorType
>>>>     func makeIterator() -> Iterator
>>>>   }
>>>> 
>>>>   protocol Collection : Sequence {
>>>>     associatedtype Iterator = IndexingIterator<Self>
>>>>     func makeIterator() -> Iterator  // redeclaration helps inference
>>>>   }
>>>> 
>>>> When a type that conforms to Collection doesn’t provide makeIterator, it gets a default one via:
>>>> 
>>>>   extension Collection where Iterator == IndexingIterator<Self> {
>>>>     public func makeIterator() -> IndexingIterator<Self> { … }
>>>>   }
>>>> 
>>>> That will still work (yay). However, simply removing associated type inference means that a collection type that *does* provide makeIterator()—but not, directly, Iterator—would change behavior:
>>>> 
>>>>   struct IntCollection : Collection {
>>>>     typealias Element = Int
>>>>     func makeIterator() -> IntCollectionIterator { … }
>>>>   }
>>>> 
>>>> With associated type inference, we infer Iterator = IntCollectionIterator and select IntCollection.makeIterator() to satisfy the makeIterator() requirement.
>>>> 
>>>> Without associated type inference, we use the default Iterator = IndexingIterator<Self> and select the makeIterator() from the protocol extension (because IntCollection.makeIterator() now returns the wrong type), which turns an error of omission into an unpleasant surprise. We might need something like near-miss checking for defaulted protocol requirements (which we discussed in the thread at http://thread.gmane.org/gmane.comp.lang.swift.devel/1799) to help find those surprises. They already exist today, of course, but removing associated type inference would make them worse.
>>>> 
>>>> Finally, one of the chief concerns is that we won’t be able to provide a nice experience when conforming to the standard library’s collection protocols. I would *love* to see some more thought to into how we can use the above tools to handle it, although I suspect the only way to do that is to implement some part of this proposal experimentally and see what it takes to get the standard library and it’s tests working again. How far can the tools above go toward reducing the need to specify various associated type witnesses in conforming types? What are the surprises?
>>>> 
>>>>   - Doug
>>>> 
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160629/61937cb7/attachment.html>


More information about the swift-evolution mailing list