<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><blockquote type="cite" class="">On Dec 14, 2015, at 1:37 AM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:</blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class=""><blockquote type="cite" class="" style="font-family: HelveticaNeue;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">func maxY(p1: P, p2: P) -> Int {</div><div class=""> return max(p1.y, p2.y) // No problems here!</div><div class="">}</div></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div><div class="">…right?</div></div></div></div></div></div></blockquote><br class="" style="font-family: HelveticaNeue;"></div><div class=""><div class="">Ah, but then you have the situation that P doesn't conform to P (it doesn't have an x that you can access). In my opinion that is just too weird an idea to be usable.</div><div class="">Personally, I have always thought that protocols intended to be used as unbound existentials (not P<A: Int>, just plain P) are different beasts entirely from the kind used as generic constraints and should be explicitly declared as such—I don't think I've ever seen a protocol that is well-used in both ways; if you have counterexamples I'd love to see them. In "existential protocols," declaring an associated type or creating a self requirement would be an error at the point of declaration. </div></div></blockquote><div class=""><br class=""></div><div class="">IMHO, it’s an artificial distinction that makes sense only if you’re acclimated to Swift’s current behavior.</div><div class=""><br class=""></div><div class="">There are plenty of situations where you really do want a generic type in the protocol, but you nonetheless find yourself in situations where you care only about the parts of the protocol that don’t depend on that generic type.</div><div class=""><br class=""></div><div class="">Here’s an example, pared down a lot but taken from an actual project:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">protocol</span> Request</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">typealias</span> ContentType</div><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(50, 62, 125);" class="">func</span> onCompletion(callback: (<span style="color: rgb(88, 126, 168);" class="">ContentType?, ErrorType?)</span> -> <span style="color: rgb(88, 126, 168);" class="">Void</span>)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> onSuccess(callback: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ContentType</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Void</span>)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(50, 62, 125);" class="">func</span> onNewData(callback: <span style="color: rgb(88, 126, 168);" class="">ContentType</span> -> <span style="color: rgb(88, 126, 168);" class="">Void</span>)</div><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><span style="font-size: 10.5px;" class=""> </span><span style="font-size: 10.5px; color: rgb(50, 62, 125);" class="">func</span><span style="font-size: 10.5px;" class=""> onFailure(callback: </span><span style="font-size: 10.5px; color: rgb(88, 126, 168);" class="">ErrorType</span><span style="font-size: 10.5px;" class=""> -> </span><span style="font-size: 10.5px; color: rgb(88, 126, 168);" class="">Void</span><span style="font-size: 10.5px;" class="">)</span></p><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> cancel()</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">struct</span> RequestBatch</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">var</span> requests: [<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Request</span>] <font color="#901000" class="">// Sadness. Despair. DOOOOM.</font></div><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> cancelAll()</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">for</span> request <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">in</span> <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">requests</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> { request.<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">cancel</span>() }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div class=""><br class=""></div><div class="">The current Swift solution is either to ditch the type safety of ContentType, or split Request into two protocols. The latter makes the API hard to read, and may decouple related protocol requirements that don’t make sense independently.</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 14, 2015, at 1:40 AM, ilya <<a href="mailto:ilya.nikokoshev@gmail.com" class="">ilya.nikokoshev@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="" style="font-family: HelveticaNeue;">You can achieve the same result more cleanly with <div class=""><br class=""></div><div class=""><div class="">func maxY<T:P, U:P>(p1:T, p2: U) -> Int {</div><div class=""> return max(p1.y, p2.y) // No problems here!</div><div class="">}</div></div></div></div></blockquote><br class=""></div><div>True, but this doesn’t generalize to other contexts, e.g. RequestBatch.requests above.</div><div><br class=""></div><div>Conceptually, at least to me, a protocol describes a set of related capabilities that together add up to a meaningful behavior. Whether some of those capabilities share a generic type is incidental, and does not fundamentally change the nature of a protocol. Protocols should be protocols.</div><div><br class=""></div><div>Java can do this via the <?> syntax:</div><div><br class=""></div><div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; color: rgb(88, 126, 168);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> interface </span>Request<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><</span>ContentType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">></span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> void onCompletion(CompletionCallback<ContentType> callback);</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> void onSuccess(SuccessCallback<ContentType> callback);</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> void onNewData(SuccessCallback<ContentType> callback);</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> void onFailure(FailureCallback<ContentType> callback);</div><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> void cancel();</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">class</span> RequestBatch</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">private</span> List<Request<?>> requests;</div><p style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">public</span> void cancelAll()</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">for</span>(Request<?> request: requests)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> { request.cancel(); }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""> }</div><div class=""><br class=""></div></div><div>And yes, “Java can do it” is a deliberate provocation! :P</div><div><br class=""></div><div>Cheers,</div><div><br class=""></div><div>Paul</div><div><br class=""></div><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px; line-height: normal;"><div style="word-wrap: break-word;" class=""><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px; color: rgb(0, 0, 0); font-family: 'Helvetica Neue'; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px; color: rgb(0, 0, 0); font-family: 'Helvetica Neue'; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px;">–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––<br class=""><a href="https://innig.net" class="">https://innig.net</a> • @inthehands • <a href="http://siestaframework.com/" class="">http://siestaframework.com/</a><br class=""><br class=""></span></span></div></span></div></div></body></html>