[swift-evolution] Require use of override keyword to override dynamically dispatched methods defined in a protocol with a default implementation
Howard Lovatt
howard.lovatt at gmail.com
Wed Jan 6 19:08:39 CST 2016
The point is that without the requirement of both final and override the
compiler doesn't know in detail what the problem is; just that there is a
problem, it doesn't have enough information (it doesn't know the
programmers intention - override and final clarify that intension). That is
irrespective of how the compiler is written.
On Thursday, 7 January 2016, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> > I don't like this solution because the compiler produces poor error
> > messages. It says that the type that implements the protocol doesn't
> conform
> > to the protocol in all three cases described below. Whereas if override
> were
> > required the compiler would say one of:
>
> I completely agree that the compiler's error messages are currently
> vague and unhelpful. I don't have any experience in terms of how the
> compiler goes about its job, but it seems to me that it's an
> orthogonal issue? Whether `override` is required everywhere or no, if
> the compiler has enough information to know that the type is
> nonconforming, surely it could be spruced up to know which methods or
> properties are missing even while maintaining today's syntax? Someone
> who's expert in this could probably chime in here. I get the sense
> from this list that the community and core team are not in favor of
> changing syntax only to make up for deficiencies in tooling, though
> honestly I don't think the syntax would be worse off if we do it your
> way.
> > I would prefer final to be required so that it is clear that this is a
> > static dispatch.
>
> I've tried to follow the other thread about this. I'm not clear that I
> fully grasp the proposal but that's my fault. Something isn't clicking
> about how final (which I understand in the context of class
> hierarchies) works in the context of protocol extensions. Would this
> mean that if a protocol extension defines a statically dispatched and
> therefore mandatory 'final' method foo() that I'm no longer allowed to
> have a method foo() in a conforming class? That seems like it could
> make a lot of things blow up especially in the context of retroactive
> modeling as discussed above. Perhaps I'm just not understanding.
>
>
> On Wed, Jan 6, 2016 at 5:56 PM, Howard Lovatt <howard.lovatt at gmail.com
> <javascript:;>> wrote:
> > Comments in-line below.
> >
> >
> > On Thursday, 7 January 2016, Xiaodi Wu via swift-evolution
> > <swift-evolution at swift.org <javascript:;>> wrote:
> >>
> >> > Another option might be to allow imported definitions to be used by a
> >> > conformance without the `override` marking to support retroactive
> >> > modeling
> >> > while requiring definitions in the same module as the conformance to
> >> > explicitly specify the `override`.
> >>
> >> That's an interesting suggestion. I don't think I'd prefer that
> >> solution, though, because I would imagine that it's during retroactive
> >> modeling of someone else's stuff that ambiguity regarding what's
> >> overridden or not might occur.
> >>
> >> I've been slow in fully understanding Greg Parker's feedback, but on
> >> reflection it may be the only way to satisfy all use cases. In
> >> Thorsten's scenario where neither the protocol and its extension nor
> >> the type is under the control of the user, making the type conform to
> >> the protocol would either require no keyword requirements regarding
> >> overriding methods (as it is, and as you suggest) or else a syntax to
> >> indicate an overriding method must exist *within the extension that
> >> conforms a type to a protocol* (as Greg suggests).
> >>
> >> Can I propose an amended solution then?
> >>
> >> (1) When a protocol requires a method (or property getter/setter,
> >> etc.) but doesn't provide a default implementation, no keyword is used
> >> anywhere since all conforming types must provide their own
> >> implementation--I suppose a requirement could be made for a keyword,
> >> but I don't know that it adds much in terms of guarding against
> >> unintended behavior; I guess that can be a continued point of
> >> discussion
> >>
> >>
> > I don't like this solution because the compiler produces poor error
> > messages. It says that the type that implements the protocol doesn't
> conform
> > to the protocol in all three cases described below. Whereas if override
> were
> > required the compiler would say one of:
> >
> > 1. If the method was completely absent or there was a typo and no
> override
> > the compiler could identify the missing method as an error on the type.
> > 2. If the method had the same signature as a protocol method but no
> override
> > (or had final) the compiler could say that override is required and
> > importantly identify the method at fault
> > 3. If the method had override but a typo the compiler could say that it
> does
> > not override a method and importantly identify the method at fault.
> > 4. If the method had both final and override the compiler could say that
> > both not allowed and importantly identify the method at fault.
> >
> > Which is much more fine grained and informative.
> >>
> >>
> >> (2) When a protocol doesn't declare a method but an extension to the
> >> protocol provides one, types implementing a method with the same
> >> signature *must not* declare it to be overriding; such protocol
> >> extension methods are not overridden because they can be invoked after
> >> upcasting
> >>
> > I would prefer final to be required so that it is clear that this is a
> > static dispatch.
> >>
> >>
> >> (3) When a protocol does declare a method, and an extension to the
> >> protocol provides a default implementation, then to override that
> >> implementation *either* the implementing type *or* an extension must
> >> use the keyword `override`
> >>
> >> (3a) In the case of an implementing type, `override func` is used
> >> instead of `func`, just as in the case of a class overriding a
> >> superclass method
> >>
> >> (3b) In the case of an extension to a type (this is the syntax I could
> >> come up with, but maybe it'll be objectionable in other ways), a
> >> method in an existing class can be retroactively made overriding by
> >> declaring `override [method signature]` with no body, similar to the
> >> way that a method is declared inside a protocol; by analogy, an
> >> overriding getter might use the syntax
> >>
> >> extension Int: BoundedType {
> >> static var min { override get }
> >> }
> >>
> >> I think the syntax proposed in (3b) has the virtue of not requiring
> >> additional keywords, being sufficiently similar to (3a) so that it's
> >> not surprising, but still sufficiently unique in that the syntax is
> >> not currently valid code and thus isn't currently used to mean
> >> anything else.
> >>
> >>
> >> On Wed, Jan 6, 2016 at 8:21 AM, Matthew Johnson <matthew at anandabits.com
> <javascript:;>>
> >> wrote:
> >> >
> >> > On Jan 6, 2016, at 3:48 AM, Greg Parker via swift-evolution
> >> > <swift-evolution at swift.org <javascript:;>> wrote:
> >> >
> >> >
> >> > On Jan 5, 2016, at 8:50 PM, Brent Royal-Gordon via swift-evolution
> >> > <swift-evolution at swift.org <javascript:;>> wrote:
> >> >
> >> > Taking inspiration from syntax used for methods in classes that
> override
> >> > methods in superclasses, require methods that override dynamically
> >> > dispatched default implementations in protocol extensions to use the
> >> > override keyword. Likewise, forbid the override keyword if the method
> >> > being
> >> > implemented instead 'masks' (would that be the right word?) a
> statically
> >> > dispatched method in a protocol extension which can nonetheless be
> >> > invoked
> >> > by upcasting to the protocol.
> >> >
> >> >
> >> > This has been suggested before, usually in the form of a separate
> >> > `implement` keyword. The main problem is that it makes it impossible
> to
> >> > write a protocol after the fact which formalizes some existing pattern
> >> > in
> >> > the types.
> >> >
> >> > What do I mean by that? Well, imagine you need generic access to the
> >> > `min`
> >> > and `max` static properties of the various integer types. There's no
> >> > existing protocol that includes those members. But you can write one
> and
> >> > then extend the integer types to conform to your new protocol:
> >> >
> >> > protocol BoundedIntegerType: IntegerType {
> >> > static var min: Self { get }
> >> > static var max: Self { get }
> >> > }
> >> > extension Int: BoundedType {}
> >> > extension Int8: BoundedType {}
> >> > extension Int16: BoundedType {}
> >> > extension Int32: BoundedType {}
> >> > extension Int64: BoundedType {}
> >> >
> >> > func printLowestPossibleValueOfValue<Integer: BoundedIntegerType>(x:
> >> > Integer) {
> >> > print(Integer.min)
> >> > }
> >> >
> >> > This only works because `min` and `max` *don't* need any special
> marking
> >> > to
> >> > be used to satisfy a requirement. Requiring a keyword like you suggest
> >> > would
> >> > remove that feature.
> >> >
> >> >
> >> > Possible solution: if you want a new protocol adoption to map to some
> >> > existing method or property then you must explicitly write that. You
> >> > can't
> >> > just adopt the protocol in an empty extension.
> >> >
> >> > extension Int: BoundedType {
> >> > static var min = Int.min
> >> > static var max = Int.max
> >> > }
> >> >
> >> > but with some other syntax that isn't ambiguous. Code completion and
> >> > compiler fix-its could suggest this when the class already implements
> >> > something suitable.
> >> >
> >> >
> >> > Another option might be to allow imported definitions to be used by a
> >> > conformance without the `override` marking to support retroactive
> >> > modeling
> >> > while requiring definitions in the same module as the conformance to
> >> > explicitly specify the `override`.
> >> >
> >> >
> >> >
> >> > --
> >> > Greg Parker gparker at apple.com <javascript:;> Runtime Wrangler
> >> >
> >> >
> >> > _______________________________________________
> >> > swift-evolution mailing list
> >> > swift-evolution at swift.org <javascript:;>
> >> > https://lists.swift.org/mailman/listinfo/swift-evolution
> >> >
> >> >
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org <javascript:;>
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> >
> >
> > --
> > -- Howard.
> >
>
--
-- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160107/436a2388/attachment.html>
More information about the swift-evolution
mailing list