swift mixed implemention of protocol method and other method,this triggered the problem.
Compiler can't judge mis-spelled method. It think it's a new method. Rust has no this problem: Impl protocolName for className { ..... } linter can't check for mis-spelled methods, on the condition that there's no explicit override syntax in Swift. Goffredo Marocchi via swift-evolution <swift-evolution@swift.org>于2016年9月20日 周二04:12写道: > +1 > > Sent from my iPhone > > On 19 Sep 2016, at 18:10, 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. > > Opinions? > > Currently, there is a JIRA bug that Set does not conform to SetAlgebra. To > > fix this issue, someone simply needs to write `extension Set : SetAlgebra { > > }` and some tests. That's literally what the bug (filed by a core team > > member) tells you to do. It's a starter bug, and if someone hasn't taken it > > yet, you the reader could have a go at it. What's neat about Swift is that > > it's super easy to provide the same functionality in your own project > > without waiting on that bug to be fixed in Swift itself. You can simply > > write a single line of code. By contrast, if your proposal were to be > > implemented, this would become much more difficult. > > > This is actively used in Swift today. For example, in the Swift > > implementation of NSScanner, you'll find the following lines: > > > ``` > > internal protocol _BitShiftable { > > static func >>(lhs: Self, rhs: Self) -> Self > > static func <<(lhs: Self, rhs: Self) -> Self > > } > > > internal protocol _IntegerLike : Integer, _BitShiftable { > > init(_ value: Int) > > static var max: Self { get } > > static var min: Self { get } > > } > > > extension Int : _IntegerLike { } > > extension Int32 : _IntegerLike { } > > extension Int64 : _IntegerLike { } > > extension UInt32 : _IntegerLike { } > > extension UInt64 : _IntegerLike { } > > ``` > > > If we adopted your proposed syntax below, it would take considerably more > > lines of boilerplate code to express the same thing. The burden increases > > significantly with the complexity of the retroactive modeling. For > > instance, if the retroactively modeled protocol had 20 requirements and you > > were retroactively conforming 20 types, that'd be at least 400 lines of > > boilerplate. > > > > Basically, the way I see it, if my class MyClass implements MyProtocol, > > providing someRequiredFunc(), there’s an “ownership” chain there > > (reading it backwards). > > > Now what happens if MyClass implements MyOtherProtocol, which also has > > someRequiredFunc()? In that case, I want to MyClass as a > > MyOtherProtocol and get another function pointer, which just happens to > > have the same human-readable name as some other property. Just because > > they have the same function signature, absolutely doesn’t mean they’re > > the same thing. > > > Now, if we strongly bind all protocol conformances to the protocol they > > implement, what happens to instance methods? They don’t belong to any > > protocol, their parent is the class itself. If you have an instance > > method called someRequiredFunc(), and you later add a conformance to > > MyProtocol, you would need to declare that it belongs to MyProtocol. If > > you don’t want it to be an API-breaking change, you have to provide a > > thunk (or we could provide a shorthand syntax which emits thunks for > > you) to let us know that MyClass::someRequiredFunc() is the same thing > > as MyClass::MyProtocol::someRequiredFunc(). > > > > Your argument is that two methods with the same name should not in any way > > conflict with each other. This is a fundamental change from the status quo. > > If we were to take your argument to its logical conclusion, any member A of > > a type T should be capable of being designated as the implementation of a > > requirement B of protocol P. In the most general case, two functions A and > > B shouldn't even need to take the same number of arguments, or arguments of > > the same type; you should be able to supply default arguments, or even > > write custom code that takes arguments for A and computes suitable > > arguments for B in order to forward A to B, and the language should allow > > you to designate A as an implementation of B. But that is simply not how > > Swift protocols are designed. > > > > Let’s take an example where retroactive modelling could go wrong. > > You’ve got different teams working on different parts of an App, and > > they’ve all got their own convention for “copy()”. Sometimes it’s a > > deep-copy, sometimes a shallow-copy, sometimes it’s used in a fragile > > way for a specific case, whatever. Now you want to go and clean that up > > by creating a “Copyable” protocol with codified guarantees. Some > > objects may already conform, others may need tweaks, and some may want > > both behaviours simultaneously (preserving the old, > > non-Copytable-compliant behaviour until the next API break), depending > > on how you look at the object. A system like this allows all of those > > different ways of looking at the object live together. You could have > > the old, non-comforming API as an extension with a FIXME to delete it > > for version 2. > > > > Even if you design a protocol called Copyable, you still need to explicitly > > extend concrete types in order to conform to Copyable. Swift does not > > automagically make anything conform to your protocol. If you choose > > *explicitly* to conform different types that don't guarantee the same > > semantics, and then you erroneously assume that they all have the same > > semantics even though you *explicitly* chose types that don't have the same > > semantics, you're the one who shot yourself in the foot, so to speak. It's > > not the fault of Swift at all. > > > > I think it’s pretty arcane that members of a type are resolved only by > > their names. If you want to provide types which allow flexible views of > > data, each view of that data needs to be completely free in its > > expressivity. > > > I would actually like to see a syntax like: > > > ``` > > let testObject = MyClass() > > let testMyProto = testObject.MyProtocol // the protocol-witness table > > for testObject as a MyProtocol. > > > testObject.MyProtocol.someRequiredFunc() // that’s one function > > testObject.someRequiredFunc() // is a different function. May happen to > > have the same implementation as above if MyProtocol was retroactively > > modelled. > > ``` > > > I think it would fit well with the dispatch system for protocol > > extensions, too. I sometimes have code like the following: > > > ``` > > protocol Base {} > > protocol Derived : Base {} > > > extension Base { > > func doSomething() { … } > > } > > extension Derived { > > func doSomething() { > > … > > (self as Base).doSomething() // Would be better if we could say > > “self.Base.doSomething()” to disambiguate instead of casting. > > } > > } > > ``` > > > > This is a complete redesign of protocols in Swift. With the emphasis on > > minimizing source-breaking changes, I doubt such a change would be in scope > > for any phase of Swift unless you could show an overwhelming benefit. > > > So yeah, a big +1 to marking protocol methods with their protocol > > (whatever the syntax ends up looking like), and actually I’d take it > > further and bake them in to the ABI. That also makes it relevant for > > Swift 4 phase 1. > > > Karl > > > > > _______________________________________________ > > 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