I definitely think Vladimir's suggestion is a great starting point, IMO.

However, I think it could be improved in one key respect where previous
proposals using `override` are superior. Namely, the proposed `implement`
keyword adds no additional safety when a type implements a protocol
requirement that doesn't have a default implementation. This is because, if
there's a "near-miss" typo in the function signature, an error is already
generated at compile time because the type doesn't conform to the stated
protocol. Currently, the error is very unhelpful, but IMO that's a
straight-up bug; improving the diagnostics for that error can be done
without evolution.

On the other hand, if we require `implement`, the simplest use case of
conforming a type to a protocol with no default implementations would take
more effort but provide no benefit to justify that additional effort.
Moreover (I think a core team member has expressed this more elegantly in
the past), there's the philosophical point that POP represents the
theoretical process by which we discover and express our discovery that
certain types happen to share common semantic characteristics. In that
conception of POP, it would be backwards to declare a certain member as
fulfilling certain protocol requirements.

So, if such a source breaking change were to be in scope for Swift, I would
suggest modifying Vladimir's proposal to use `override` instead and
requiring the keyword only when a default implementation is being
overridden. To accommodate retroactive conformance, we could either propose
that `extension Foo : Bar` is automatically understood to contain members
that override default implementations (as Vladimir has essentially
suggested), or stipulate that we must write `extension Foo : override Bar`.
This has the advantage of not introducing an additional keyword and avoids
the seemingly reduplicative spelling `extension Foo : implement Bar` (for
what else would an `extension Foo : Bar` reasonably do but implement the
requirements of Bar?).


On Mon, Sep 19, 2016 at 3:10 PM, Goffredo Marocchi via swift-evolution <
swift-evolution@swift.org> wrote:

> If Swift 4 will make it impossible to tackle this again, I do not think
> discussing this can be avoided for Swift 3.1... I am afraid we are rushing
> into Swift 4 a bit too quickly, but perhaps it is just silly old me :).
>
> Sent from my iPhone
>
> On 19 Sep 2016, at 19:18, Charles Srstka via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Sep 19, 2016, at 12:10 PM, Vladimir.S via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On 17.09.2016 6:32, Xiaodi Wu via swift-evolution wrote:
>
>
> Let me give a concrete example of how retroactively modeling is used.
>
>
> Karl is suggesting interesting but complex and IMO too much code-breaking
> idea that I don't believe can be implemented at all in a reasonable amount
> of time to be a part of Swift as soon as possible, to address the discussed
> issue with protocols.
>
> I wonder what objections could be made on the solution proposed below,
> which should solve a major(IMO) number of issues with protocol conformance
> and introduce only 1 keyword. Such solution will make Swift better as
> Protocol-Oriented language and later we can even improve it, but it can
> already solve a big number of issues:
>
> 1. As soon as possible we add 'implement' keyword which is required to
> mark method/property that was defined in type or extension exactly to
> conform to some protocol.
>
> 2. The 'implement' required only at a moment of 'direct' conformance, i.e.
> when you declare methods/props of the type/extension that explicitly
> conformed to protocol.
>
> 3. Retrospective conformance will not require this keyword and will work
> for now just like it is working today.
>
> 4. Later, if this will be possible at all, we can extend this model to
> support separate implementation of protocols with same requirements in the
> same type, explicit protocol name in implemented methods/props and
> improvements for retrospective conformance. For example some variants for
> *future* improvements:
>
> 4.1 Different implementation for different protocols
> class Foo : ProtocolA, ProtocolB {
>  implement(ProtocolA) func foo() {...}
>  implement(ProtocolB) func foo() {...}
> }
> class Foo : ProtocolA, ProtocolB {
>  implement ProtocolA {
> func foo() {...}
>  }
>  implement ProtocolB {
> func foo() {...}
>  }
> }
> etc
>
> 4.2 Retrospective conformance: What is the main problem with retrospective
> conformance? As I see it now(correct me, if I missing something), the
> problem arises in such situation:
> * we *expect* that some method(s) in type will play the role of
> implementation of protocol's requirements, so we retrospectively conform
> that type to the protocol.
> * but protocol has default implementation for its requirements
> * and type's methods, that we *expect* to play roles for protocol
> implementation, has different parameters or slightly different method name
> at all.
>
> I.e. when we have this set of code logic:
>
> type T {
>  func foo()
> }
>
> protocol P {
>  func foo(x: Int)
> }
>
> extension P {
>  func foo(x: Int) {...}
> }
>
> extension T : P { // expect foo in T will play role of P.foo
> }
>
> I support the opinion that it is not an option to require to explicitly
> list conformed methods/props in type extension for retrospective
> conformance.
> But I do believe we need a way to *express our intention* regarding the
> retrospective conformance: do we expect that type already contains
> implementation for some protocol's requirements OR we are aware that
> protocol can have defaults for some methods and our type does not contains
> some implementations.
>
> So, the solution here IMO is some syntax to express that intention. Right
> now I think that we can use current syntax "extension T : P" to keep it
> working as it now works: "I'm aware of all the names, defaults etc. Treat
> this as usually you did". But for example something like "extension T:
> implement P {..}" or "extension T: P(implement *) {..}" will say that we
> *expect* that all requirements of P protocol should be implemented inside T
> type. Or some syntax inside extension to specify the list of methods/props
> we expect to be implemented in T. Or "extension T : P(implement foo,
> bar(x:y:)) {..}".. Should be discussed.
>
> But again, IMO this could be discussed later, after we'll have 'implement'
> for most important place - in type definition for method/prop that we
> created exactly for the conformed protocol.
>
>
> I would be completely +1 on this.
>
> Charles
>
> _______________________________________________
> 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

Reply via email to