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.
···
On 23.09.2016 11:05, Maximilian Hünenberger wrote:
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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@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@gmail.com >>>>> <mailto:xenadu@gmail.com>> wrote:
On Sep 20, 2016, at 4:34 PM, Dave Abrahams via swift-evolution >>>>>> <swift-evolution@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing
list swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution