[swift-evolution] two protocols with the same method name

Andrew Bennett cacoyi at gmail.com
Mon Jan 11 03:06:44 CST 2016


I agree with zhaoxin, self.Marriageable.ring doesn't seem to provide the
same interface as the protocol. It is similar to how it would be done with
existing swift code, and doesn't risk sharing a name with static properties
and typealiases on the type.

Something we still need to handle though is associated and Self type
requirements.
 * Should you be able to apply similar namespaces to an associated type?
 * How do you cast to a protocol with an associated type?

For example:

protocol P1 {
    typealias Element

    func get() -> Element

}
protocol P2 {
    typealias Element
    func get() -> Element
}
struct X: P1, P2 {
    typealias P1.Element = Int
    typealias P2.Element = Float
    func get() -> P1.Element { fatalError() }
    func get() -> P2.Element { fatalError() }
}
struct Y: P1, P2 {
    typealias Element = Int
    func P1.get() -> Element { fatalError() }
    func P2.get() -> Element { fatalError() }
}

let e1 = (x as P1).get()
let e2 = (x as P2).get()


There will be errors on e1 and e2 like this:

*protocol 'P1' can only be used as a generic constraint because it has Self
or associated type requirements*


You may be able to get around it with a generic function, but the ugliness
of that solution should be considered in our choices for this proposal.

It would be nice (in general) to be able to do this:

let e3 = (x as P1<Int>).get()
let e4 = (x as P2<Float>).get()


However it's unclear what type e3 and e4 should be, there's currently no
support for automatic synthesis of type-erased structures, and there's no
meta-type I know of that can stand-in.

Perhaps associated and Self type requirements are out-of-scope of this
proposal, but I thought it was worth mentioning.



On Mon, Jan 11, 2016 at 4:26 PM, 肇鑫 <owenzx at gmail.com> wrote:

> I don't think self.Marriageable.ring is a good idea. As self.Type
> conforms Marriageable protocol, and a protocol is not a property of a
> class/struct/enum.
>
> Let's go back with the definition of the Protocol.
>
> A protocol defines a blueprint of methods, properties, and other
>>> requirements that suit a particular task or piece of functionality. The
>>> protocol can then be adopted by a class, structure, or enumeration to
>>> provide an actual implementation of those requirements. Any type that
>>> satisfies the requirements of a protocol is said to conform to that
>>> protocol.
>>
>>
>>> In addition to specifying requirements that conforming types must
>>> implement, you can extend a protocol to implement some of these
>>> requirements or to implement additional functionality that conforming types
>>> can take advantage of.
>>
>>
>>>
> So if there are some independent protocols accidentally sharing the same
> vars or functions, this does not violate the definition of the protocol.
> Should the compiler warns the programmer? Maybe, as we can not sure there
> must be conflicts. So I think the alert level is between warning and
> silence.
>
> Let's also see the solutions. The solutions in other languages inspire us
> what to do. One is to change the properties names, the other is to cast the
> type to the protocol.
>
> I think the prior method is much easier to go with. As currently,  you
> can't name a store properties in extension, and you can't have two
> properties with the same name in extension. However, there is also a
> problem after you rename the property. As it is no longer the name that
> defined in the protocol, you can use it with (self as Protocol).name. So
> maybe we can use lable to solve the problem.
>
> Basically:
>            type A: Marriageable, CallReceivable {
>
>      var Marriageable.ring ring: String? { ... }
>      var CallReceivable.ring ringtone: String? { ... }
> }
>
> to call it :
>
> (self as Marriageable).ring or self.ring
> (self as CallReceivable).ring or self.ringtone
>
>
> zhaoxin
>
>
> On Mon, Jan 11, 2016 at 8:17 AM, Wallacy via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> I Like this C#'s "Explicit Interface Implementation".
>> The cast to call is understandable, it's good, but just think about. If
>> we use "self.Marriageable.ring" or "variable.Marriageable.ring" will make
>> more symmetrical with the implementation? "dot protocol" can be used to all
>> "explicit call", ambiguous or not.
>>
>> Em dom, 10 de jan de 2016 às 21:49, Andrew Bennett via swift-evolution <
>> swift-evolution at swift.org> escreveu:
>>
>>> Sorry if this is already mentioned, but I quite like C#'s "Explicit
>>> Interface Implementation" approach:
>>>
>>> https://msdn.microsoft.com/en-us/library/ms173157.aspx
>>>
>>>
>>> Basically:
>>>
>>> var Marriageable.ring: String? { ... }
>>> var CallReceivable.ring: String? { ... }
>>>
>>> to call it you could do self.ring if it was unambiguous, otherwise:
>>>
>>> (self as Marriageable).ring
>>> (self as CallReceivable).ring
>>>
>>>
>>>
>>> On Mon, Jan 11, 2016 at 9:51 AM, Brent Royal-Gordon via swift-evolution
>>> <swift-evolution at swift.org> wrote:
>>>
>>>> > By giving warning simply for same name, it will be quite annoying
>>>> when the project run into this situation without any wrong. For example:
>>>> >
>>>> > protocol ForwardIndexType : _Incrementable {
>>>> >     @warn_unused_result
>>>> >     public func advancedBy(n: Self.Distance) -> Self
>>>> > }
>>>> >
>>>> > extension ForwardIndexType {
>>>> >     @warn_unused_result
>>>> >     public func advancedBy(n: Self.Distance) -> Self
>>>> >     @warn_unused_result
>>>> >     public func advancedBy(n: Self.Distance, limit: Self) -> Self
>>>> >     @warn_unused_result
>>>> >     public func distanceTo(end: Self) -> Self.Distance
>>>> > }
>>>> >
>>>> > protocol BidirectionalIndexType : ForwardIndexType
>>>> > extension BidirectionalIndexType {
>>>> >     @warn_unused_result
>>>> >     public func advancedBy(n: Self.Distance) -> Self
>>>> >     @warn_unused_result
>>>> >     public func advancedBy(n: Self.Distance, limit: Self) -> Self
>>>> > }
>>>>
>>>> Firstly, for methods and subscriptors the "name" would actually
>>>> encompass the entire signature, so `advancedBy(_:)` and
>>>> `advancedBy(_:limit:)` would not conflict because they have different
>>>> signatures.
>>>>
>>>> Secondly, `ForwardIndexType` and `BidirectionalIndexType` are *not*
>>>> unrelated protocols—one of them conforms to the other. Thus, we can assume
>>>> that `BidirectionalIndexType` knows about `ForwardIndexType`'s `advancedBy`
>>>> methods and intends for its versions to have compatible semantics.
>>>>
>>>> If instead `BidirectionalIndexType` did *not* conform to
>>>> `ForwardIndexType`, and `RandomAccessIndexType` tried to conform to both
>>>> `ForwardIndexType` and `BidirectionalIndexType`, *then* we would get an
>>>> error, because two independent protocols would have declared `advancedBy(_:
>>>> Self.Distance) -> Self` methods and it's possible they meant for them to
>>>> have different semantics.
>>>>
>>>
>>>> --
>>>> Brent Royal-Gordon
>>>> Architechies
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
>
> --
>
> Owen Zhao
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/90f79ef7/attachment.html>


More information about the swift-evolution mailing list