<div dir="ltr">Here's a simplified section of code I'm writing for mapping some data from over the wire<div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><br></div><div>public protocol Transform {</div><div> // a bunch of stuff</div><div>}</div><div><br></div><div>public protocol Key {</div><div> // a bunch of stuff</div><div>}</div><div><br></div><div>extension String: Key { /* conforming stuff */ }</div><div><br></div><div>public protocol JSONType { }</div><div>extension Int: JSONType { }</div><div><br></div><div>public enum Bind<T>: Key {</div><div> case transform(Key, T)</div><div> // a few more cases, every case must have a Key, we forward all of Key's methods through each case.</div><div>}</div><div><br></div><div>public func map<T: JSONType>(field: inout T, binding: Key) {</div><div> print(field)</div><div>}</div><div><br></div><div>public func map<T, U: Transform>(field: inout T, binding: Bind<U>) {</div><div> print(field)</div><div>}</div><div><br></div><div>class SpecialTransform: Transform { }</div><div><br></div><div>var s = Int()</div><div>// Ambiguity here.</div><div>map(field: &s, binding: Bind.transform("data.stuff", SpecialTransform()))</div></blockquote></div><div><br><div>Probably would be better to make `Bind` not conform to `Key`, would just require a bunch of refactoring in places where I've used the two interchangeably. However, one of the benefits of having `Bind: Key` is that it enforces that every additional case has a `Key` which will always be true for this data structure.</div></div><div><br></div><div><div>I was thinking the first `map` would change to</div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>public func map<T: JSONType, K: Key>(field: inout T, binding: K)</div></div></blockquote><div><br></div><div>But to have `K != Bind<Any>`, Bind<Any> would have to be the super type of all other Bind<T>s which currently isn't true anyway so this is kind of dead on arrival.</div><div><br></div><div><div>Interestingly though, when I change the signature to </div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>public func map<T: JSONType, K: Key>(field: inout T, binding: K)</div></blockquote><div><br></div><div>Instead of "Ambiguous use of...", the program compiles and calls this method instead of the overload with Bind<U>. Not only is this not the function I want called, but this seems like inconsistent behavior with the type checker (compiling vs throwing an "Ambiguous use of..." error).</div><div>Should I report a bug here or am I missing something?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 28, 2017 at 9:35 AM, Matthew Johnson <span dir="ltr"><<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Feb 28, 2017, at 11:33 AM, Joe Groff <<a href="mailto:jgroff@apple.com" target="_blank">jgroff@apple.com</a>> wrote:</div><br class="m_-3967364951621681103Apple-interchange-newline"><div><blockquote type="cite" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br class="m_-3967364951621681103Apple-interchange-newline">On Feb 28, 2017, at 9:23 AM, Matthew Johnson <<a href="mailto:matthew@anandabits.com" target="_blank">matthew@anandabits.com</a>> wrote:<br><br><br><blockquote type="cite">On Feb 28, 2017, at 11:04 AM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br><br><br><blockquote type="cite">On Feb 27, 2017, at 4:34 PM, Rex Fenley via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br><br>I often find myself running into situations where I'll receive "Ambiguous use of..." for overloaded functions or operators. In every case these situations would be easily solved if I could specify "Generic != CertainType" in the where clause of one of the overloads so I can disambiguate the cases. Could this be added to language?<br></blockquote><br>Do you have a concrete example where you need this? It'd be good to know whether the types are ambiguous due to type checker bugs, or whether there's a principle by which they could be naturally ordered. Instead of overloading, can you do the type test via `if !(x is CertainType)` within a single implementation?<br></blockquote><br>The best use case I can think of is if we had enum cases where the associated value is a subtype of the enum:<br><br>enum Result<T, E> where E: Error, T != E {<br> case some(T) -> T<br> case error(E) -> E<br>}<br></blockquote><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">I don't think that's a good design for that type. I can see the desire for a subtype relationship between T and Result<T, E>, but no good reason for the error to also be a subtype. That != constraint would have to be propagated through anything using `Result<T, E>` as well.</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></div></blockquote><div><br></div></span><div>Ok, just change it to a fully generic Either type then. I’m not arguing for or against this constraint, just pointing out a use case that is enabled by it. It’s reasonable to argue that we don’t want to support this use case.</div><br><blockquote type="cite"><div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">-Joe</span></div></blockquote></div><br></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><span><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:16px;font-family:Arial;background-color:transparent;font-style:italic;vertical-align:baseline;white-space:pre-wrap">Rex Fenley</span><span style="font-size:16px;font-family:Arial;background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">|</span><span style="line-height:1.15;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">IOS DEVELOPER</span><br></p></span><span><br><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><img src="https://lh5.googleusercontent.com/xMgzw3JkFL3DLkdwyq0WxJzKs_XP57gVVCaBMvgi1FKCjSeue0xdx3JZeCWBlxN4KRHhHOfdvJbc1N-AjTwXcKIq4cjJg9H7iaFpQ8WbO4N3c9Y5dzi19cPOs_owPquuqw" width="250px;" height="53px;" style="border:none"></span></p><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><a href="https://www.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);font-weight:bold;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">Remind.com</span></a><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">| </span><a href="http://blog.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">BLOG</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><a href="https://twitter.com/remindhq" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">FOLLOW US</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="text-decoration:underline;font-size:11px;font-family:Arial;color:rgb(17,85,204);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><a href="https://www.facebook.com/remindhq" style="text-decoration:none" target="_blank">LIKE US</a></span></p></span></div></div>
</div>