Sent from my iPad

> On Jun 25, 2016, at 12:41 PM, Austin Zheng <austinzh...@gmail.com> wrote:
> 
> 
>> On Jun 25, 2016, at 6:23 AM, Matthew Johnson <matt...@anandabits.com> wrote:
>> 
>> Hi Austin,
>> 
>> I’m sorry to say, but this proposal makes me really sad.  I consider 
>> associated type inference one of the more elegant aspects of Swift.  It 
>> would be very unfortunate to lose it.  
> 
> There are lots of "elegant" things that Swift could do, but has chosen not to 
> do for pragmatic reasons (e.g. generalized implicit conversions, type 
> inference that crosses statement boundaries). Given how terrible the 
> development experience can be right now in the worst case, I would happily 
> trade off some measure of convenience for better tooling.

I understand the technical issues underlying the proposal.  I wasn't sure how I 
would respond to this until Dmitri posted an alternative.  IMO if we can solve 
the technical issues without giving up inference that is a huge win.  It looks 
viable to me (as a non-expert - I hope a compiler engineer can confirm this).

If this is indeed a viable alternative then there is no tradeoff necessary and 
the discussion becomes one of style / preference.  In that discussion I fall 
strongly on the side of protocol requirement guided inference.

> 
>> 
>> I am really pleased to see that Dmitri has offered an alternative that looks 
>> very reasonable.  I’m hoping the Doug or Chris (or someone else from the 
>> core team) can chime in on the feasibility of this alternative.  If it is 
>> considered viable and Dmitri isn’t able to write the proposal I would be 
>> happy to do so.
>> 
>> If the alternative isn’t viable and we must proceed with a proposal to 
>> remove inference I think there is one crucial thing to consider that isn’t 
>> discussed in this proposal: retroactive modeling.  As far as I can tell, 
>> this proposal will *prohibit* some types from conforming to some protocols.  
>> Specifically, if a type defines a typealias with a name that matches the 
>> name of an associatedtype in a protocol it would not be possible to 
>> retroactively model that protocol.  Because of the name conflict an 
>> associatedtype declaration would not be allowed and the existing typealias 
>> would not meet the requirement.  Consider this example:
> 
> I actually think that the delineation between `associatedtype` and 
> `typealias` should make this legal, and will change the proposal as such. It 
> should be legal to bind an associated type to a type alias, and it should be 
> possible to define a type alias that shadows (but does not conflict with) an 
> associated type definition. This would fix the issue with retroactive 
> modeling.

IIUC you're saying a type is allowed to have an `associatedtype` and 
`typealias` (or nested type) both bound to the same name as long as they 
resolve to the same type.  Is that correct?  That would at least preserve 
current expressiveness.

> 
>> 
>> // Module A
>> public struct S {
>>     public typealias Foo = Int
>> }
>> 
>> // Module B
>> public protocol P {
>>     associatedtype Foo
>> }
>> 
>> // Module C
>> import A
>> import B
>> 
>> // compiler error: `S` does not meet the `Foo` associatedtype requirement
>> extension S : P {
>>     // compiler error: cannot define associatedtype `Foo` for `S` which 
>> already declares typealias `Foo`
>>     associatedtype Foo = String
>> }
>> 
>> I cannot support any proposal that breaks retroactive modeling in this way.
> 
> Addendum aside, retroactive modeling is already suboptimal or broken in 
> multiple ways today - try conforming a protocol with associated type 
> 'Element' to a different protocol whose 'Element' means something completely 
> different.

Did you mean conforming a type to two protocols with an 'Element' 
associatedtype?

I consider that issue to be in the realm of multiple conformances rather than 
retroactive modeling.  I can still 

> 
>> 
>> Another item that is not mentioned in this proposal is that typealias is not 
>> the only way to meet an associatedtype requirement in the language today.  
>> For example, this code is legal:
>> 
>> protocol Foo {
>>     associatedtype Bar
>> }
>> struct S : Foo {
>>     struct Bar {}
>> }
> 
> I don't see how this is relevant.
> 
> struct S : Foo {
>   associatedtype S = Bar
>   struct Bar { }
> }

Do you mean this?

struct S : Foo {
  associatedtype Bar = Bar
  struct Bar { }
}

That would preserve current expressiveness.

> 
>> 
>> If we *must* drop inference I prefer the alternative of just doing that: 
>> dropping inference, but otherwise leaving things alone.  All associated type 
>> requirements would need to be explicitly satisfied using one of the 
>> mechanisms that is currently valid for satisfying a non-inferred associated 
>> type requirement.  The ability to satisfy these requirements in a variety of 
>> ways is a *benefit* that provides valuable flexibility.
> 
> I disagree that it's a benefit. It certainly saves a couple of keystrokes, 
> but you gain or lose no expressive power from this proposal, addendum 
> included. I'm happy to expand the alternatives section to discuss the other 
> ways to satisfy associated type requirements, though.

Thank you for adding the clarifications.  I feel a little better knowing we 
wouldn't lose expressive power, but still prefer the directed inference 
suggested by Dmitri.

> 
>> 
>> I agree that something should look for a good solution to the subclass 
>> typealias issue, but I don’t think this is it.  Ideally we would find a 
>> solution that works well in the presence of retroactive modeling making code 
>> such as the following valid:
>> 
>> // module A
>> protocol P1 {
>>     associatedtype Foo
>> 
>>    @infers(Foo)
>>     var foo: Foo { get }
>> }
>> // module B
>> protocol P2 {
>>     associatedtype Foo
>> 
>>     @infers(Foo)
>>     func bar() -> Foo
>> }
>> 
>> // module C
>> class Base {
>>     let foo: String = "foo"
>> }
>> class Derived : Base {
>>     func bar() -> Int { return 42 }
>> }
>> 
>> // module D
>> import A
>> import B
>> import C
>> import D
>> extension Base : P1 {}
>> extension Derived : P2 {}
>> 
>> We don’t always control the protocol or type definitions we want to make 
>> work together.  The ability to make code that “should work together” 
>> actually do so with minimal fuss is one of the great things about Swift.  
>> Any time we interfere with retroactive modeling we increase the need for 
>> boilerplate adapter types, etc.
>> 
>> One detail appears to be implied by the proposal but isn’t explicitly 
>> stated.  Specifically, it looks like the intent is that other than only 
>> being valid when used to meet a protocol requirement, associatedtype 
>> otherwise works like a typealias.  It would be good to have this behavior 
>> clarified if the proposal moves forward.
>> 
>> -Matthew
>> 
>> 
>> 
>>> On Jun 25, 2016, at 12:50 AM, Austin Zheng via swift-evolution 
>>> <swift-evolution@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.
>>> 
>>> Best,
>>> Austin
>>> _______________________________________________
>>> 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

Reply via email to