[swift-evolution] [Pitch] Remove type-inference for stored property

Vladimir.S svabox at gmail.com
Wed Apr 12 08:32:46 CDT 2017


On 12.04.2017 15:35, Xiaodi Wu wrote:
> As I explained on Twitter, the behavior is initially counterintuitive but in many 
> ways the least surprising result.
> 
> (First, you are incorrect about P requiring a mutable property. That is not what var 
> means in a protocol.)

Yes, sorry, my mistake. But actually this does not change anything for this example:

protocol P {
	var value : Int32 {get set} // get+set
}

extension P {
	var value : Int32 {get{return 10} set{}}
}

class C : P {
	let value : Int = 4_000_000_000 // let constant
}


> 
> However, you are right that two properties named value are being allowed. It seems 
> strange at first but consider:
> 
> Given: a protocol P with only one requirement, but with a default implementation for 
> that requirement. One would expect that any type T could retroactively conform to P. 
> After all, either T has its own implementation of the requirement or it does not.
> 
> If the requirement is a property and not a method, and T has an identically named but 
> not identically typed property, we allow this sort of "overloading" which is very 
> much like overloading on the return type. This fulfills the expectation above that T 
> can conform to P. Even requiring a warning in this scenario would break retroactive 
> conformance.
> 
> The behavior at the call site is not harmful. A user of T may or may not see that it 
> conforms to P. This is because conformance can be retroactive. Thus, when using an 
> instance of T, references to the property are to T's own implementation. However, if 
> the user can see P and the conformance T : P, they can always explicitly request P's 
> differently typed implementation explicitly by using "as" (just like selecting an 
> overloaded method with a different return type).
> 
> The behavior that is unexpected and potentially harmful is for the author of a type T 
> trying to conform to P. It falls into the category of near-misses that includes 
> unintentional typos in method names, etc. It is no more surprising than any of those 
> cases where you, say, get the argument label spelled slightly wrong and end up 
> without an intended override of a default implementation but two methods instead.

Not agree here. We *can* have methods with the same name but different 
argument/result type defined in the *same* type.
But we can't have property with the same name but different type in the same type.

> 
> As mentioned earlier on this list, the user experience of writing a conforming type 
> is suboptimal, and there are likely to be clever ways for the compiler or other tools 
> to help. However, ripping out type inference or breaking retroactive conformance is 
> not the way forward to solving this issue.

I agree that retroactive conformance is important feature, but in this particular 
case, the situation IMO is not the same as with near-miss for methods.

And actually I still believe that such near-miss(even for methods) will be usually an 
hidden/delayed error, when user do expect that type's methods/props will conform the 
type to protocol, not protocol's default method. And I do believe that be able to 
prevent such error is more important than no-worry retroactive conformance. (and then 
spent a number of hours to debug such hard-to-find bug)

Plus, if we *want* we can suggest a way to silence such warning even for retroactive 
conformance. The question if the problem worth to be solved.

> On Wed, Apr 12, 2017 at 05:15 Vladimir.S via swift-evolution 
> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>     On 12.04.2017 7:19, Jaden Geller wrote:
>      >
>      >> On Apr 7, 2017, at 4:07 AM, Vladimir.S via swift-evolution
>      >> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>> wrote:
>      >>
>      >> On 07.04.2017 10:21, Daniel Duan via swift-evolution wrote:
>      >>> Hi all,
>      >>>
>      >>> In a discussion about inferring parameter types from default value,
>      >>> Slava brought up some performance problems caused by type inference for
>      >>> stored properties in side types:
>      >>>
>      >>>
>     https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033882.html
>      >>>
>      >>> Towards the end, the post mentioned that some Swift team members
>      >>> contemplated requiring types for stored properties in type declarations.
>      >>> I think this idea deserves some more attention. Hence this last minute
>      >>> idea-floating.
>      >>>
>      >>> In addition to solving a performance headache in implementation,
>      >>> there're always the general benefit of making type declartion more
>      >>> explicit and readable (clarity for reader should out-weigh pleasure of
>      >>> the author). Making the language slightly more consistent (we are not
>      >>> inferring types for default parameter values in function anyways).
>      >>>
>      >>> The cons for doing this are obvious too: the inference makes the
>      >>> language feels more friendly and is, undoubtedly, a beloved feature for
>      >>> many. This would be a source breaking change.
>      >>>
>      >>> Just thought I'd float the idea to gather some quick reaction. What do
>      >>> y'all think?
>      >>
>      >> Although it seems like only an implementation-side problem(i.e. "let's just
>     improve
>      >> implementation"), I see a benefits to require type for stored property *if* it is
>      >> not obvious what the type is for *reader*. I.e. if we have something like this, I
>      >> don't think we should require a type:
>      >> struct S {
>      >>  var x = 0
>      >> }
>      >
>      > I think there is value in requiring a type annotation there. For example, this bug
>      > would be avoided: https://twitter.com/benjaminencz/status/851892622213783552
> 
>     I believe the pointed problem is much wider, than type-inference and I even think
>     this is bug(in design?) that should be fixed at least with warning.
> 
>     Please consider this example:
> 
>     protocol P {
>              var value : Int32 {get}
>     }
> 
>     extension P {
>              var value : Int32 {return 20}
>     }
> 
>     class C : P {
>              let value = 4_000_000_000
> 
>              /// or even this:
>              // let value : Int = 4_000_000_000
>     }
> 
>     First, as class C conforms to P protocol, it must have *mutable* 'value' property
>     Second, currently it seems like class C has two 'value' properties with different
>     type. It is very strange(the principle of less surprise, yes?) and as we can see
>     dangerous behavior. Was bug to bugs.swift.org <http://bugs.swift.org> submitted?
>     If so, what was the reply of
>     the core team?
> 
>      >
>      >>
>      >> but I do think it will be better to require a type in such cases :
>      >>
>      >> struct S{
>      >>  var x = something(SomeType(), 123, "123") // can be generic func
>      >> }
>      >>
>      >>
>      >>
>      >>>
>      >>> Daniel Duan _______________________________________________
>      >>> swift-evolution mailing listswift-evolution at swift.org
>     <mailto:listswift-evolution at swift.org>
>      >>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>      >>> https://lists.swift.org/mailman/listinfo/swift-evolution
>      >>>
>      >> _______________________________________________
>      >> swift-evolution mailing list
>      >> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>      >> https://lists.swift.org/mailman/listinfo/swift-evolution
>      >
>     _______________________________________________
>     swift-evolution mailing list
>     swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>     https://lists.swift.org/mailman/listinfo/swift-evolution
> 


More information about the swift-evolution mailing list