I agree this is a very... tricky part of Swift, and that many have stated
it is expected behaviour.
I think this is fundamentally incorrect from a design standpoint with the
concept of a protocol as an agreed interface, rather than an agreed
implementation. By adding a Protocol Extensions, we have started to mix
implementation with interface, which is understandable as those with the
same interface often conform to the same behaviour.
That said, I think if my conforming to the protocol means I need to do
extra work for my specific implementation case, then letting someone
circumvent that by simply referring to me as the protocol is both dangerous
and lets the protocol's extension implementation have mixed priority. My
unique use case should be more important than the implementation that makes
sense for the generic case.
My view is protocol extensions should a "default", nothing more. If you
implement, you override. This behaviour preserves protocols as an agreed
interface with additional default logic rather than a conflicting set of
implementations.
I think I've stated this view before and been shot down, but I'm not sure.
Rod
On 11 Feb 2017, at 9:54 am, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:
Robert, this is a tricky part of Swift. I raised the same point in my
very first email to this list a year and a half ago, and the response was
that no default/implement/override keyword was desired and that this
behavior is intentional. It has since been raised multiple times on this
list to the same conclusion.
The idea here is that protocol extension methods that are not protocol
requirements are statically dispatched and can be shadowed but not
overridden. If you read through some of the Swift-Evolution proposals,
you'll see that there are several designs that actually seek to take
advantage of this behavior. I can't recall which of these were actually
implemented in that way, but it does indeed show that the behavior has its
uses.
Many have suggested some sort of keyword to distinguish overriding and
shadowing. However, every such proposed design thus far breaks retroactive
conformance in some subtle way. It's hard to search the archives, but there
are hundreds of emails on this topic.
On Fri, Feb 10, 2017 at 15:57 Goffredo Marocchi via swift-evolution < >> swift-evolution@swift.org> wrote:
I remain very unconvinced that type casting should change code being
executed...
Sent from my iPhone
On 10 Feb 2017, at 21:04, David Waite via swift-evolution < >> swift-evolution@swift.org> wrote:
On Feb 10, 2017, at 12:41 PM, Robert Ryan via swift-evolution < >> swift-evolution@swift.org> wrote:
I’m hard pressed to think of a situation where you’d want the current
Swift 3 behavior of the first example (where you can override a protocol
default implementation but you only want that override used when you
reference the class itself, but not when you reference the protocol as a
type).
Thats easy - the extension methods are not related to protocol
conformance. The type implementing the protocol may not even know there
*is* an extension method, or that method could be added either later or by
yet other third party code.
As such, the type may not be overriding the extension method at all - the
protocol-implementing types may have their own method with a conflicting
name doing similar (or not) logic. It would not be appropriate for someone
calling the protocol extension method to get different behavior simply
because a type declared a similar named method.
In other words, without the method being declared on the protocol,
override behavior between an extension and type would be similar to unsafe
“duck” typing. There is no agreement by the type that they are conforming
to extension behavior, only to the protocol’s behavior.
IMHO the issue actually goes the other way
- there is no way to indicate that an extension method to a protocol is
meant to declare ‘default’ behavior, e.g. represents a partial
implementation for types conforming to the protocol.
- there is no way to indicate that a type property/method ‘implements’
the functionality of a protocol.
The lack of a distinction between extensions declaring random methods and
declaring default implementation behavior is obviously an element of
confusion. Both points become an issue if the protocol method signatures
ever changes - the extension could no longer be providing a default
implementation, or a type may silently switch from their own implementation
to the default implementation provided by the extension.
-DW
If there are such examples, then add a “build setting” to allow you to
turn off this warning, or add some keyword to the declaration of the
default implementation that indicates that you’re allowing it to be
overridden, but protocol types won’t use it (e.g. nondynamic).
Personally, I’d just add the warning and call it a day (because I don’t
know why you’d ever want the current Swift 3 behavior).
_______________________________________________
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
_______________________________________________
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