[swift-evolution] protocol can only be used as a generic constraint because it has Self or associated type requirements

Marc Knaup marc at knaup.koeln
Mon Dec 14 07:20:18 CST 2015


A protocol X could fulfill conformance to a protocol Y.

protocol SomeProtocol: Equatable {}
enum SomeType1: SomeProtocol { case Case }
enum SomeType2: SomeProtocol { case Case }

func == (a: SomeProtocol, b: SomeProtocol) -> Bool { // should be allowed
to use protocol directly
  switch (a, b) {
  case let (a, b) as (SomeType1, SomeType1): return a == b
  case let (a, b) as (SomeType2, SomeType2): return a == b
  default: return false
  }
}

// Equatable requirement is fulfilled for SomeProtocol
let a: SomeProtocol = SomeType1.Case // should be allowed to use protocol
directly
let b: SomeProtocol = SomeType2.Case
print(a == b) // should print "false"

var array = [SomeProtocol]() // should be allowed to use protocol directly

That kind of conformance fulfillment should not be inherited though or else
this could cause a recursion, i.e. types implementing the protocol must
still conform to

Since SomeProtocol has internal visibility all types and protocols
explicitly declaring conformance are even known at compile-time.
For that reason implementing the equality operator for the protocol
wouldn't even be necessary. The compiler does already know that all types
conforming to the protocol are equatable and could even generate the
equality operator.


I find the suggestion from Paul Cantrell very useful where you can use all
properties and methods of the protocol which do not depend on an associated
type or Self.

var array = [Hashable]()
// …
for element in array {
    print(element.hashValue)
}

Who cares that it doesn't fulfill Equatable conformance yet?


On Mon, Dec 14, 2015 at 8:40 AM, ilya via swift-evolution <
swift-evolution at swift.org> wrote:

> You can achieve the same result more cleanly with
>
> func maxY<T:P, U:P>(p1:T, p2: U) -> Int {
>   return max(p1.y, p2.y)   // No problems here!
> }
>
> On Mon, Dec 14, 2015 at 10:03 AM, Paul Cantrell via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> On Dec 13, 2015, at 11:56 PM, Dave Abrahams via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> On Dec 13, 2015, at 3:55 PM, Marc Knaup via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Is there any info yet if and how we will be able to refer to instances of
>> protocols that have associated types?
>>
>>
>> As far as I know, this isn't a solvable problem.
>>
>>
>> What is the difficulty in supporting this?
>>
>>
>> Here's a simple example:
>>
>> protocol P {
>>   typealias A
>>   var x: A { get set }
>> }
>>
>> struct Y : P {
>>   var x: Int
>> }
>>
>> struct Z : P {
>>   var x: String
>> }
>>
>> func f(p1: P, p2: P) {
>>   p1.x = p2.x // assigning an Int to a String?
>> }
>>
>>
>> p1.x = p2.x should be a compiler error, because there’s not enough type
>> information. But that shouldn’t stop a programmer from doing this:
>>
>> protocol P {
>>   typealias A
>>   var x: A { get set }
>>   var y: Int
>> }
>>
>> struct Y : P {
>>   var x: Int
>>   var y: Int
>> }
>>
>> struct Z : P {
>>   var x: String
>>   var y: Int
>> }
>>
>> func maxY(p1: P, p2: P) -> Int {
>>   return max(p1.y, p2.y)   // No problems here!
>> }
>>
>> …right?
>>
>> Cheers, P
>>
>>
>> _______________________________________________
>> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151214/81257783/attachment.html>


More information about the swift-evolution mailing list