<div dir="ltr">When I said that the problem would exist internally, I meant that there would still be two conflicting associatedtype declarations inside MyType.<div>This can be perfectly solved by conformance-with-renaming. Example:</div><div><br></div><div>extension MyType : Computer {</div><div> from Computer rename Internal to Internal1</div><div> associatedtype Internal1 = Int</div><div>}</div><div>extension MyType : Computer {</div><div> from Computer rename Internal to Internal2</div><div> associatedtype Internal2 = Double</div><div>}</div><div><br></div><div>Then MyType should play well both in contexts of T: Computer where Internal == Int and T: Computer where Internal == Double.</div><div><br></div><div>It potentially convers a broad range of conflicts, such as conflicting functions and conflicting properties.</div><div>We could include composition operations of traits in Swift's protocols, most notably, rename and exclude.</div><div>Niall Young <<a href="mailto:niall@iinet.net.au">niall@iinet.net.au</a>> 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.</div><div><br></div><div>And still I think I'll propose generic protocols if noone does that before.</div><div><br></div><div>- Anton</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-06-09 18:37 GMT+03:00 Vladimir.S <span dir="ltr"><<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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).<br>
<br>
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.<span class=""><br>
<br>
> func test<T: Computer>(input: inout T) {<br>
> let internal: T.Internal = input.prepare()<br>
> input.compute(internal)<br>
> }<br>
><br>
> What is T.Internal , Int or Double? I showed the problem very eplicitly,<br>
> but it would exist hidden in a much greater number of cases.<br>
<br></span>
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.<br>
I.e. we should be forced to call `test` simething like this:<br>
<br>
test(MyType() as Computer where .Internal = Int)<br>
// just MyType() will produce something like "multiply conformance to Computer with different assotiated types, need explicit cast to one of concrete implementation"<br>
<br>
This is just abstract thoughts with abstract syntax, don't know if there is something useful in them at all :-)<div><div class="h5"><br>
<br>
On 09.06.2016 18:01, Антон Жилин wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
A problem with my solution is that there is a conflict between<br>
associatedtype declarations inherited from From<Int> and From<Double>.<br>
Or in your example, associatedtype Element = Int and associatedtype<br>
Element = String are in conflict.<br>
Another example:<br>
<br>
protocol Computer {<br>
associatedtype Internal<br>
mutable func prepare() -> Internal<br>
mutable func compute(input: Internal)<br>
}<br>
<br>
extension MyType : Computer<Int> { }<br>
extension MyType : Computer<Double> { }<br>
<br>
func test<T: Computer>(input: inout T) {<br>
let internal: T.Internal = input.prepare()<br>
input.compute(internal)<br>
}<br>
<br>
What is T.Internal , Int or Double? I showed the problem very eplicitly,<br>
but it would exist hidden in a much greater number of cases.<br>
<br>
It's not that such resolution is impossible, but solution of Chris does not<br>
have this problem at all: generic types do not create associated type<br>
requirements.<br>
In this case, there is no ambiguity:<br>
<br>
protocol Computer<Internal> {<br>
mutable func prepare() -> Internal<br>
mutable func compute(input: Internal)<br>
}<br>
<br>
extension MyType : Computer<Int> { }<br>
extension MyType : Computer<Double> { }<br>
<br>
func test<I, T: Computer<I>>(input: inout T) {<br>
let internal: I = input.prepare()<br>
input.compute(internal)<br>
}<br>
<br>
test(MyType() as Computer<Int>) // no ambiguity<br>
test(MyType() as Computer<Double>) // no ambiguity<br>
<br>
- Anton<br>
<br>
2016-06-09 17:25 GMT+03:00 Vladimir.S <<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a><br></div></div>
<mailto:<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>>>:<div><div class="h5"><br>
<br>
I like the idea as associatedtype is playing the role of generic type<br>
and in extension we conforms to the protocol with some specific generic<br>
type as associated type.<br>
<br>
I mean the first idea probably could be<br>
protocol From<T> {<br>
init(_ value: T)<br>
}<br>
but "protocols do not allow generic parameters; use associated types<br>
instead", so it seems natural to express concrete type as associated<br>
type for protocol in generic syntax <Type><br>
<br>
Probably alternative syntax could look like:<br>
<br>
extension Int : From where .FromType = Float { }<br>
<br>
Also, it seems like this proposal could help to solve a problem with<br>
the same name of associated type in different protocols:<br>
<br>
protocol One {<br>
associatedtype Element<br>
func foo(t: Element)<br>
}<br>
<br>
protocol Two {<br>
associatedtype Element<br>
func bar(t: Element)<br>
}<br>
<br>
struct OneTwo : One, Two {<br>
func foo(t: Int) {}<br>
func bar(t: String) {}<br>
}<br>
// type 'OneTwo' does not conform to protocol 'Two'<br>
// candidate has non-matching type '(t: String) -> ()' [with Element =<br>
Element]<br>
<br>
So, as I understand, will be possible<br>
struct OneTwo : One, Two<String> {<br>
func foo(t: Int) {} // OneTwo.Element will be Int<br>
func bar(t: String) {}<br>
<br>
}<br>
<br>
On 08.06.2016 22:07, Антон Жилин via swift-evolution wrote:<br>
<br>
==Motivation==<br>
<br>
protocol From {<br>
associatedtype FromType<br>
init(_ value: FromType)<br>
}<br>
<br>
The problem is, one type cannot implement multiple From "conversions".<br>
<br>
==Proposed solution==<br>
<br>
Allow specifying all associated types using generic syntax.<br>
<br>
extension Int : From<Float> { }<br>
extension Int : From<Double> { }<br>
<br>
This is only allowed in conformance declarations.<br>
<br>
==Future directions==<br>
<br>
We can replace all *Convertible protocols with >From and Into, which<br>
will be<br>
defined similarly to Rust.<br>
<br>
- Anton<br>
<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br></div></div>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
<br>
</blockquote>
</blockquote></div><br></div>