[swift-evolution] [Draft] Allow multiple conformances to the same protocol
Антон Жилин
antonyzhilin at gmail.com
Thu Jun 9 11:12:16 CDT 2016
When I said that the problem would exist internally, I meant that there
would still be two conflicting associatedtype declarations inside MyType.
This can be perfectly solved by conformance-with-renaming. Example:
extension MyType : Computer {
from Computer rename Internal to Internal1
associatedtype Internal1 = Int
}
extension MyType : Computer {
from Computer rename Internal to Internal2
associatedtype Internal2 = Double
}
Then MyType should play well both in contexts of T: Computer where
Internal == Int and T: Computer where Internal == Double.
It potentially convers a broad range of conflicts, such as conflicting
functions and conflicting properties.
We could include composition operations of traits in Swift's protocols,
most notably, rename and exclude.
Niall Young <niall at iinet.net.au> is working on this problem, but his
proposal is going to add new separate "trait" declarations for that, a
decision which I don't quite understand.
And still I think I'll propose generic protocols if noone does that before.
- Anton
2016-06-09 18:37 GMT+03:00 Vladimir.S <svabox at gmail.com>:
> Hmm.. In case we *can* have generic `protocol Computer*<Internal>*{..}` -
> then yes, it seems like a best solution(generic protocols and using of
> generic types).
>
> As for hypothetical solution without generic protocol, then we need to
> separate two `Internal` assotiated types (i.e. separate implementation of
> Computer(Internal=Int) and Computer(Internal=Double) protocols). I.e. it
> seems like the same protocol with different assotiated type should be
> treated as different protocol.
>
> > func test<T: Computer>(input: inout T) {
> > let internal: T.Internal = input.prepare()
> > input.compute(internal)
> > }
> >
> > What is T.Internal , Int or Double? I showed the problem very eplicitly,
> > but it would exist hidden in a much greater number of cases.
>
> As I see the situation: our type implemented two protocols, one Computer
> with Internal = Int, and second with Internal = Double. So, in case we
> *can* implement the same protocol with different assotiated types - we
> *must* have a requirement and the ability to separate these implementation
> *before* calling this func.
> I.e. we should be forced to call `test` simething like this:
>
> test(MyType() as Computer where .Internal = Int)
> // just MyType() will produce something like "multiply conformance to
> Computer with different assotiated types, need explicit cast to one of
> concrete implementation"
>
> This is just abstract thoughts with abstract syntax, don't know if there
> is something useful in them at all :-)
>
>
> On 09.06.2016 18:01, Антон Жилин wrote:
>
>> A problem with my solution is that there is a conflict between
>> associatedtype declarations inherited from From<Int> and From<Double>.
>> Or in your example, associatedtype Element = Int and associatedtype
>> Element = String are in conflict.
>> Another example:
>>
>> protocol Computer {
>> associatedtype Internal
>> mutable func prepare() -> Internal
>> mutable func compute(input: Internal)
>> }
>>
>> extension MyType : Computer<Int> { }
>> extension MyType : Computer<Double> { }
>>
>> func test<T: Computer>(input: inout T) {
>> let internal: T.Internal = input.prepare()
>> input.compute(internal)
>> }
>>
>> What is T.Internal , Int or Double? I showed the problem very eplicitly,
>> but it would exist hidden in a much greater number of cases.
>>
>> It's not that such resolution is impossible, but solution of Chris does
>> not
>> have this problem at all: generic types do not create associated type
>> requirements.
>> In this case, there is no ambiguity:
>>
>> protocol Computer<Internal> {
>> mutable func prepare() -> Internal
>> mutable func compute(input: Internal)
>> }
>>
>> extension MyType : Computer<Int> { }
>> extension MyType : Computer<Double> { }
>>
>> func test<I, T: Computer<I>>(input: inout T) {
>> let internal: I = input.prepare()
>> input.compute(internal)
>> }
>>
>> test(MyType() as Computer<Int>) // no ambiguity
>> test(MyType() as Computer<Double>) // no ambiguity
>>
>> - Anton
>>
>> 2016-06-09 17:25 GMT+03:00 Vladimir.S <svabox at gmail.com
>> <mailto:svabox at gmail.com>>:
>>
>>
>> I like the idea as associatedtype is playing the role of generic type
>> and in extension we conforms to the protocol with some specific
>> generic
>> type as associated type.
>>
>> I mean the first idea probably could be
>> protocol From<T> {
>> init(_ value: T)
>> }
>> but "protocols do not allow generic parameters; use associated types
>> instead", so it seems natural to express concrete type as associated
>> type for protocol in generic syntax <Type>
>>
>> Probably alternative syntax could look like:
>>
>> extension Int : From where .FromType = Float { }
>>
>> Also, it seems like this proposal could help to solve a problem with
>> the same name of associated type in different protocols:
>>
>> protocol One {
>> associatedtype Element
>> func foo(t: Element)
>> }
>>
>> protocol Two {
>> associatedtype Element
>> func bar(t: Element)
>> }
>>
>> struct OneTwo : One, Two {
>> func foo(t: Int) {}
>> func bar(t: String) {}
>> }
>> // type 'OneTwo' does not conform to protocol 'Two'
>> // candidate has non-matching type '(t: String) -> ()' [with Element =
>> Element]
>>
>> So, as I understand, will be possible
>> struct OneTwo : One, Two<String> {
>> func foo(t: Int) {} // OneTwo.Element will be Int
>> func bar(t: String) {}
>>
>> }
>>
>> On 08.06.2016 22:07, Антон Жилин via swift-evolution wrote:
>>
>> ==Motivation==
>>
>> protocol From {
>> associatedtype FromType
>> init(_ value: FromType)
>> }
>>
>> The problem is, one type cannot implement multiple From
>> "conversions".
>>
>> ==Proposed solution==
>>
>> Allow specifying all associated types using generic syntax.
>>
>> extension Int : From<Float> { }
>> extension Int : From<Double> { }
>>
>> This is only allowed in conformance declarations.
>>
>> ==Future directions==
>>
>> We can replace all *Convertible protocols with From and Into,
>> which
>> will be
>> defined similarly to Rust.
>>
>> - Anton
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto: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/20160609/71e0f683/attachment.html>
More information about the swift-evolution
mailing list