<div><div><div><div class="gmail_quote"><div dir="auto">On Tue, Jun 27, 2017 at 16:44 David Moore via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
<div name="messageBodySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif">There are a few ways in which this issue could be addressed. The first, and most desirable approach in my opinion, would be full inferencing of a given associatedtype and a generic. An example of the foregoing would be the following:
<div><br></div>
<div>protocol Foo {</div>
<div> associatedtype ABC</div>
<div>}</div>
<div><br></div>
<div>struct Bar<ABC> : Foo {</div>
<div> // Would normally require some sort of workaround to complete the typealias implementation of the protocol’s associatedtype, but it should be inferred in this case because there is no explicit typealias statement.</div>
<div>}</div>
<div><br></div>
<div>The inferencing would indeed take place in the above example. But now let’s consider the possibility of breaking source compatibility, as in, is this compatible or not?</div>
<div><br></div>
<div>struct Bar<ABC>: Foo {</div>
<div> typealias ABC = ArbitraryType // An inference would not take place here because there’s nothing to infer. The associated type `ABC` is explicitly defined as being `ArbitraryType`.</div>
<div>}</div>
<div><br></div>
<div>The above method shall be referred to as Option #1. It would seem like Option #1 is source compatible, in addition to solving the original problem, and potentially introduces some connivence to protocol conformance. For all existing implementations of associatedtypes and so on, I don’t think Option #1 affects them at all, unless I’m completely missing something.</div></div></div></blockquote><div dir="auto"><br></div></div></div></div></div><div><div class="gmail_quote" dir="auto"><div dir="auto">As I mentioned already, this is source breaking for any type Bar that conforms to Foo where Bar.T is currently distinct from the inferred type of Foo.T, because the inference would become ambiguous.</div><div dir="auto"><br></div><div dir="auto">In addition, it cannot be right to infer this automatically, as it would be saying that a typealias named T and an associated type that happens also to be named T can be assumed to have the same semantics even during retroactive conformance. This is essentially stringly typing.</div><div dir="auto"><br></div><div dir="auto">More generally, I continue not to understand the motivation. You mentioned that you wished for there to be a distinction between associated types and generic type inferences, and this seems to be the opposite of that. Jaden offered another example, but I am not sure I appreciate why this feature is desirable or even necessary in that scenario. In Jaden’s example, as in yours, there is nothing in the protocol itself that demands that Optional.Wrapped must be the same as OptionalType.Wrapped; this is, rather, something that is the choice of the author who conforms the type to the protocol, at the point of conformance. I fail to see why OptionalType.Wrapped cannot simply have another name, such as WrappedType.</div></div></div><div><div><div><div class="gmail_quote"><div dir="auto"><br></div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div name="messageBodySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif"><div>So Option #1 seems like a good candidate.</div>
<div><br></div>
<div>Onto Option #2, the idea of using base types to express more explicit definitions to solve the initial problem. When it comes to using a base type to correctly disambiguate these types of situations, it may be familiar to some who like a more concrete implementation, although it eliminates possible convenience, but still requires knowledge. Options #2 would look something like the following.</div>
<div><br></div>
<div>protocol Foo {</div>
<div> associatedtype ABC<br></div>
<div>}</div>
<div><br></div>
<div>struct Bar<ABC>: Foo {</div>
<div> typealias Foo.ABC = Bar.ABC // Quite explicit and communicates the solution clearly.<br></div>
<div>}</div>
<div><br></div>
<div>Options #2, as you can see above, would also be source compatible because it would not impose on already defined typealias’ or other implementations. This could be an opt-in feature. However, I don’t know if it is as nice as just pure inference, which doesn’t seem too much more difficult than this would be, but I’m not sure about that.</div>
<div><br></div>
<div>There is also a third option (referred to as Option #3), which could be the combination of both Option #1 and Option #2. However, there may be some syntactically-based issues that can arise in such a situation.</div>
<div><br></div>
<div>Let me know what everyone thinks about these possible solutions, they are by no means concretely defined as of this time, but they could be useful.</div>
</div></div><div>
<div name="messageReplySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif"><br>
On Jun 27, 2017, 2:08 PM -0400, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>, wrote:<br>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #1abc9c"><br>
<div>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #e67e22">
<div>On Jun 27, 2017, at 12:39 PM, Jaden Geller via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div>
<br class="m_6683613351832414367m_-5616478053871264042m_3868769850581362697Apple-interchange-newline">
<div>
<div style="word-wrap:break-word">I’ve run into this issue many times in the real world as well. For example, consider the following protocol:
<div><br></div>
<div>
<div style="margin:0px 0px 0px 34px;font-size:14px;line-height:normal;font-family:Monaco"><span style="color:#c900a4">protocol</span> OptionalType {</div>
<div style="margin:0px 0px 0px 67.9px;font-size:14px;line-height:normal;font-family:Monaco"> associatedtype Wrapped</div>
<div style="margin:0px 0px 0px 34px;font-size:14px;line-height:normal;font-family:Monaco">}</div>
</div>
<div><br></div>
<div>It is not possible to conform `Optional` to this protocol because its generic type is already named `Wrapped`. Only when the associated type can be inferred is conformance possible.</div>
<div><br></div>
<div>I definitely think we need a solution, but I don’t know what that solution should be.</div>
</div>
</div>
</blockquote>
<div><br></div>
<div>I agree. I have run into this as well and have been frustrated by it. It isn’t clear to me what the best solution is but I’d love to see one that could make it into a 4.x release.</div>
<br>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #e67e22">
<div>
<div style="word-wrap:break-word">
<div><br></div>
<div>Cheers,</div>
<div>Jaden Geller<br>
<div><br>
<div>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #3498db">
<div>On Jun 23, 2017, at 3:52 PM, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div>
<br class="m_6683613351832414367m_-5616478053871264042m_3868769850581362697Apple-interchange-newline">
<div>There could be source-breaking implications for such a feature, especially with retroactive conformance. Therefore, I think this could be very tricky and I'd want to be convinced that the benefits are very great to risk such a disturbance. Here, I think the problem is rather mild, and here's why:<br>
<br>
It is true that, in your example specifically, renaming T to U is the only solution (that I know of, anyway). However, for any "serious" protocol P, there's likely to be a required property of type P.T, or a function that takes an argument of type P.T or returns a value of type P.T. Therefore, implementing that requirement in Bar with a corresponding property/argument/return value of type Bar.T would generally do the trick.<br>
<br>
Have you got any real-world examples where you're running into this issue?<br>
<br>
<div class="gmail_quote">
<div>On Fri, Jun 23, 2017 at 17:03 David Moore via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div>
<blockquote class="gmail_quote" style="margin:5px 5px;padding-left:10px;border-left:thin solid #d35400">Hello Swift Evolution,<br>
<br>
This may have already been discussed before, but I just came across a bothersome language aspect which reminded me to propose a solution. Currently, if we want to add generics to a protocol the only way to do so is with associated types. I am quite fine with the current approach with respect to those semantics.<br>
<br>
There is, however, a weakness that is built in with using associated types. That weakness is the lack of associated type and generic inference. To be more clear about what I mean, take the following as an example.<br>
<br>
protocol Foo {<br>
associatedtype T<br>
}<br>
<br>
The foregoing protocol is quite basic, but uses an associated type with the name “T.” Giving the associated type that name will illustrate the dilemma encountered later on down the pipeline.<br>
<br>
struct Bar<T> : Foo {<br>
// What am I supposed to do? The name is used for both the generic and the type alias Foo needs for conformance.<br>
typealias T = T // Error!<br>
}<br>
<br>
The above illustrates a situation where we want to connect the generic, which is supposedly named appropriately, and the protocol’s associated type. There is no elegant solution for this at the moment. All I could do is the following.<br>
<br>
struct Bar<U> : Foo {<br>
typealias T = U // Not nearly as readable.<br>
}<br>
<br>
Now, there may be a few ways to go about adding support for generic inference. The compiler as it is already does some awesome inference get when it comes to generics, so why not take it a step further? I propose the introduction of a keyword, or anything else that could work, to specify explicitly what a given type alias declaration would do when it comes to inferencing. Requiring a keyword would ensure source compatibility remains intact, and it would also make the code more readable.<br>
<br>
I don’t know if this would be something that people could find useful, but I surely would. The implicit mapping of an associated type and a given generic by their names, would be a natural development.<br>
<br>
Let me know if this is just useless, or if could be a potential feature.<br>
<br>
Thank you,<br>
David Moore<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<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></blockquote>
</div>
_______________________________________________<br>
swift-evolution mailing list<br>
<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" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote>
</div>
<br></div>
</div>
</div>
_______________________________________________<br>
swift-evolution mailing list<br>
<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" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote>
</div>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<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" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote>
</div>
</div>
_______________________________________________<br>
swift-evolution mailing list<br>
<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>
</blockquote></div></div></div></div>