[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