[swift-evolution] Mark protocol methods with their protocol

Vladimir.S svabox at gmail.com
Fri Sep 23 05:47:57 CDT 2016


On 23.09.2016 11:05, Maximilian Hünenberger wrote:
> I'd also say that one or two keywords are superior than the protocol naming
> approach in terms of implementation simplicity (for the core team).
>
> My suggestions:
>
> Either "conform" or "implement" should be a required keyword for all
> properties/functions which implement a protocol (also in protocol extensions)
>

> "override" should be used if a default implementation or a member of a
> superclass is overridden.

Maximilian, again, you *do not know* if the conformed protocol, that has no 
default implementations *at the moment of your code writing* will or will 
not have default implementations at the *moment of compilation*.
Consider this scenario:

Step 1. You got 3rd party source file for your project, and you don't 
want/have no rights to change it, probably it is shared source used also in 
other projects, that code contains:

protocol A { func foo() }

class B : A {
	conform func foo() {...}
}

all is OK with this code, no default implementation, B.foo marked with 
`conform`.

Step 2. In your project in some of your files you decided to add default 
implementation of protocol A:

extension A {
	implement func foo() {...}
}

Now, your project will not compile - B.foo() must me marked with 'override' 
as protocol `A` has default implementation of foo().
If you change `conform` to `override` in 3rd party source file, it will not 
compile in some other project where no default implementation defined for 
`A` protocol.

That is *why* I believe the `override` as requirement as marker for 
protocol implementation method/prop is the best solution. See, in case 
`override` will be required, the initial source file will be like this:

protocol A { func foo() }

class B : A {
	override func foo() {...} // implementation
}

and it will compile ok : if A has default implementation and if A has no 
default implementation.

So, after you added default implementation in your project - no changes 
should be made to that 3rd party source file.


>
> If you are overriding a default implementation of a protocol "conform" /
> "implement" is also required.
>
> // Retroactive conformance (old behavior) but only in extensions
> extension Foo: @retroactive Baz {
>     // only some members of Baz are implemented here (they need the keywords)
>     // the other members outside the extension don't need any additional
> keywords
>     // note: you can use "@retroactive" and "conform" in conjunction
> }
>
>
> *Future directions:*
> "conform(ProtocolName)" / "override(ProtocolName)" can be used to disambiguate.
>
> // reducing boilerplate
> extension Foo: conform Bar {
>     // These declarations can only implement Bar and don't need the
> "conform" keyword
> }
>
> *Final question:*
> Should we also require a marker for implemented protocol members in the
> interface?:
>
> protocol Foo {
>     defaulted func foo()
> }
> extension Foo {
>     implement func foo()
> }
>
>
> Best regards
> Maximilian
>
> Am 22.09.2016 um 16:44 schrieb Vladimir.S via swift-evolution
> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>
>> On 22.09.2016 11:10, Jean-Denis Muys via swift-evolution wrote:
>>> I watched this thread with a lot of attention, starting neutral. You
>>> must say that Karl won me over. His proposal would make Swift more
>>> expressive, and less error prone in cases of protocol conformance with
>>> name collisions. I am at this point +1
>>
>> Actually I also support Karl's suggestion in general. It is trying to
>> solve IMO important problems and make Swift's protocol programming safer
>> and less fragile. Also it adds new interested features for working with
>> protocols.
>>
>> But in reality, I don't feel like his suggestion could be accepted by
>> core team and community and even if it could be supported, it seems for
>> me that *implementation* of his proposal requires a huge amount of time
>> and big changes in how Swift is working currently. (Probably some one who
>> knows Swift internals could comment regarding this)
>> So, theoretically we'd have these improvements not in near future and I
>> think the problem discussed is very important to be addressed in Swift as
>> soon as possible.
>> I base my opinion also on previous discussions regarding similar subjects.
>>
>> My suggestion regarding a marker for protocol implementation method/prop
>> in type - solves most of the addressed problems with protocol conformance
>> and with fragile of such conformance, and adds one new keyword (or even
>> zero - right now I think the `override` is better choice for such
>> "marker"). I believe this proposal could be implemented with much less
>> amount of work and with less changes to current internals of Swift and to
>> current code base, and so we can have such a big improvement in Swift
>> soon. So my intention was to suggest solution that can dramatically
>> improve Swift's protocol programming with "small" amount of changes for
>> compiler(internals) and for existed sources.
>>
>> But it seems like the direction chosen by the core team and supported by
>> many in community - is just a warning if extension conforming type to
>> protocol contains unrelated to that protocol methods/props. I see that
>> this solution can improve protocol programming in some areas, but does
>> not address some IMO important issues we discussed in the thread :
>>
>> * Currently extension can not have stored properties. So, if we want to
>> implement protocol's props as stored properties - we can't move them to
>> extension. So to implement this soulution - we need stored properties in
>> extensions. It is not clear if and when they are expected.
>>
>> * This solution will not require the safety(regarding protocol
>> conformance) from a developer, it will only inform and only if protocol
>> conformance defined in extension. So, when you use 3rd party source code
>> - your project will not be protected for the discussed problems.
>>
>> * To write safe code I can't group methods/props as I want, I have to
>> declare a number of extensions per-protocol (in case my type conforms to
>> a number of protocols)
>>
>> * This solution does not solve problem of near-miss signature of method
>> definition in protocol extension like here:
>> protocol A { func foo() }
>> protocol B : A {}
>> extension A { func foo() }
>> extension B { func voo() } // typo. how to "mark" this should be impl?
>> "my" suggestion:
>> extension A { override func foo() }
>> extension B { override func foo() }
>>
>> * Not clear how to write safe code with that approach if we implement
>> protocol requirement in derived class, but conformance was declared in
>> base (but not implemented) :
>> protocol P { func foo() }
>> extension P { func foo() }
>> class A : P {}
>> class B { func foo() } // we can't move this to extension, B already
>> conforms to P
>> , and in opposite to "my" `override` requirement for implementation, if
>> `A` will add its own foo() implementation - we'll have to change B's
>> definition(need to add `override` for B.foo )
>> "my" suggestion:
>> class B { override func foo() }
>>
>>
>>>
>>> Jean-Denis
>>>
>>> Sent from my iPhone
>>>
>>>> On 22 Sep 2016, at 07:15, Karl via swift-evolution
>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>
>>>> I would like to make it a requirement if not inside a protocol
>>>> extension which declares a conformance, and actually build the
>>>> protocol name in to the member in an ABI-breaking way. We could make
>>>> it additive by generating forwarding thunks from the old symbols to
>>>> the new ones, but it would be better if we could just solve the
>>>> overlapping-members problem before then.
>>>>
>>>> That would mean you never get collisions between protocol members.
>>>> There’s loads of amazing stuff we can do with that ability, and ways
>>>> we can extend it to reduce a lot of boilerplate that occurs when you
>>>> want to have multiple representations of the same data (String is just
>>>> an example).
>>>>
>>>> I don’t really care about the syntax we need to make it liveable. We
>>>> could automatically insert the protocol names for unambiguous members
>>>> at call-site, or something else.
>>>>
>>>> This thread was originally about making the *syntax* a requirement; I
>>>> agree with that, and I would actually take it one (or several) steps
>>>> further, solving other problems along the way.
>>>>
>>>>> On 22 Sep 2016, at 06:46, Russ Bishop <xenadu at gmail.com
>>>>> <mailto:xenadu at gmail.com>> wrote:
>>>>>
>>>>>
>>>>>> On Sep 20, 2016, at 4:34 PM, Dave Abrahams via swift-evolution
>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>
>>>>>>
>>>>>>> on Tue Sep 20 2016, Karl <razielim-AT-gmail.com
>>>>>>> <http://razielim-AT-gmail.com>> wrote:
>>>>>>>
>>>>>>> I think the best way is to prefix the member name with the
>>>>>>> protocol, e.g:
>>>>>>>
>>>>>>> protocol MyProto { var aVariable : Int func aFunction() } class
>>>>>>> MyClass : MyProto { var MyProto.aVariable : Int func
>>>>>>> MyProto.aFunction() { … } }
>>>>>> ...
>>>>>>> CC-ing Dave A, to understand better if this fits with the vision
>>>>>>> of protocols
>>>>>>
>>>>>> I generally agree with Doug.  The canonical way to indicate “this
>>>>>> method/property/type implements a requirement of protocol P”
>>>>>> should be to define the entity in an extension that also adds
>>>>>> conformance to P. If that's inadequate indication in some way we
>>>>>> should find a way to enhance it.  I wouldn't mind the notation
>>>>>> above, but only as a fallback, not a reuquirement.
>>>>>>
>>>>>> -- -Dave _______________________________________________
>>>>>
>>>>> Indeed this is exactly how C# handles Interfaces (protocols). The
>>>>> default is the exact same way Swift works - by matching names. If
>>>>> there is a collision you specify Protocol.memberName. Its simple and
>>>>> in the years I was writing C# code it was flexible enough to cover
>>>>> most reasonable scenarios, without adding a bunch of boilerplate.
>>>>>
>>>>> Russ
>>>>>
>>>>
>>>> _______________________________________________ swift-evolution
>>>> mailing list 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
>>>
>> _______________________________________________
>> 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