I was wondering why the following is not allowed, and if we could possible allow it in future versions of the language?
public protocol Example {
...
}
// Assume that the following are defined in a separate
// module without the ability to modify `Example.`
public protocol Countable {
...
}
extension Example: Countable {
...
}
Could you give an example where this could break something? And if it is dangerous, don’t we already have that danger when you extend someone else’s concrete type to conform to some protocol?
But that’s not the same thing right, at least it doesn’t seem to achieve what I would want. I want Int (and all other types that are Countable) to automatically conform to Example just by virtue of being Countable.
public protocol Example {
}
// Assume that the following are defined in a separate
// module without the ability to modify `Example.`
public protocol Countable {
}
///
protocol MyProto: Example & Countable {}
extension MyProto {
func someDefault(){print("Hello")}
}
extension Int: MyProto {}
1.someDefault() // Hello
Now that I think about it, it's pretty similar to class extension, though I'm not fond of extending other's class to begin with.
This is even more dangerous since you're adding conformance, not only to a single protocol, but also all classes that extend from it, but I'm splitting a hair here.
The reason I want to do this is exactly that. Think about type class derivation in other languages (e.g., Scala). There you can define derivation rules even outside the module in which an original type class was defined and that enables a lot of powerful features for building good APIs. I don't believe it's dangerous in that you already get halfway there with extensions to concrete types. The Int: MyProto example above still applies today and I don't consider that a problem. Aside from whether or not this is useful feature to have though, I am wondering if there are any compiler implementation reasons that make it hard to support with the current model for extensions.
But this is not the same, here you are extending Int, I think OP wants to extend Countable, not individual types. At least that's what I'm asking about, sorry to hijack the question if he wanted something else.
I think this has a slightly different meaning. This line says: "extend every concrete T that conforms to OtherProtocol to also conform to SomeProtocol".
extension OtherProtocol : SomeProtocol {}
Instead would work (in my head at least) also for existentials of OtherProtocol without a concrete type.
My assumption is based on the fact that existentials of a protocol do not conform to it.
extension Int: OtherProtocol {}
class A {
var a: OtherProtocol // With the generic extension way is NOT also SomeProtocol, but with the protocol conformance extension is
var b: Int // Is also SomeProtocol in both ways
}
Yes I agree. Also, I believe that my question is simpler than existentials. At a very basic level, I am wondering why it's not currently possible to define such extensions. Is there a specific compiler limitation that prevents us from allowing that?
I don’t really understand the explanation in the Jira link but it seems that it should at least be possible to make all concrete types that conform to ProtocolX also conform to ProtocolY in one go, since it is possible to extend each individual type?
Thanks. @owenv! This helped clarify some of the related problems. In the meantime, I also find this as a good justification for this limitation. Related to this note, I would love to see multiple conformances to the same protocol be supported for clearly mutually exclusive cases.