<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="">MOTIVATION:<div class=""><br class=""></div><div class="">Suppose we have a bunch of peppers, and we’d like to make a function to pick them. We could just take an array, but Swift supports many types of sequence types beyond a simple array, and it would be nice to support those as well, particularly since we have this one client who stores his peppers in a custom sequence type called “Peck”, and we like to prevent him from having to convert to arrays all the time. We can do this with generic functions:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Pepper {}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pick<PepperType:</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">.Iterator.Element == </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// pick a peck of peppers</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> peck: [</span><span style="font-variant-ligatures: no-common-ligatures" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">] = ...</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">pick</span><span style="font-variant-ligatures: no-common-ligatures" class="">(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">peck</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div></div></div><div class=""><br class=""></div><div class="">However, this convenience method falls down as soon as we have a peck of *pickled* peppers:</div><div class=""><br class=""></div><div class=""><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">struct</span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;" class=""> PickledPepper: </span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">Pepper</span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;" class=""> {}</span></div><div class=""><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> peck = [</span><span style="font-variant-ligatures: no-common-ligatures" class="">PickledPepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">()]</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">pick</span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">(peppers: </span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">peck</span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">)</span> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// error: Generic parameter ‘PepperType’ could not be inferred</span></div></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px;" class="">We can fix that by declaring the generic constraint to take any type that conforms to Pepper, instead of Pepper itself:</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Pepper {}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> PickledPepper: </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pick<PepperType:</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(peppers: </span><span style="font-variant-ligatures: no-common-ligatures;" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures;" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">.Iterator.Element: </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// pick a peck of peppers</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> peck = [</span><span style="font-variant-ligatures: no-common-ligatures" class="">PickledPepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">()]</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">pick</span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">(peppers: </span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">peck</span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">)</span> </span><span style="color: rgb(0, 132, 0); font-variant-ligatures: no-common-ligatures;" class="">// works :-)</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div style="margin: 0px; line-height: normal;" class="">However, this now fails if we try to pass in a collection of items still typed as Peppers:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> peck: [</span><span style="font-variant-ligatures: no-common-ligatures" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">] = [</span><span style="font-variant-ligatures: no-common-ligatures" class="">PickledPepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">()]</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">pick</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">peck</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)</span> </span><span style="color: rgb(0, 132, 0); font-variant-ligatures: no-common-ligatures;" class="">// error: Generic parameter ‘PepperType’ could not be inferred</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div style="margin: 0px; line-height: normal;" class="">The workaround is to declare the convenience method twice:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pick<PepperType:</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">.Iterator.Element == </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// pick a peck of peppers</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pick<PepperType:</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">.Iterator.Element: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// do the same exact thing!</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">This leads to a lot of copy-paste code, the non-ideal nature of which should be clear. Unfortunately, when this has come up on the list in the past, it has been mentioned that there are some cases where an existential of a protocol does not conform to the protocol itself, so it is impossible to make : always match items that are typed to the protocol.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">PROPOSED SOLUTION:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">I propose for Swift 4 a new operator, :==, which would match not only a protocol, but any type that conforms to the protocol, like so:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pick<PepperType:</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">PepperType</span><span style="font-variant-ligatures: no-common-ligatures" class="">.Iterator.Element :== </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// </span>promptly pick a peck of plain or possibly pickled peppers</div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> peckOfPeppers: [</span><span style="font-variant-ligatures: no-common-ligatures" class="">Pepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">] = [</span><span style="font-variant-ligatures: no-common-ligatures" class="">PickledPepper</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">()]</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">pick</span><span style="color: rgb(0, 0, 0); font-variant-ligatures: no-common-ligatures;" class="">(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">peckOfPeppers</span><span style="color: rgb(0, 0, 0); font-variant-ligatures: no-common-ligatures;" class="">)</span></div></div></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class=""> peckOfPickledPeppers = [</span><span style="font-variant-ligatures: no-common-ligatures;" class="">PickledPepper</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">()]</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">pick</span><span style="color: rgb(0, 0, 0); font-variant-ligatures: no-common-ligatures;" class="">(peppers: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">peckOfPickledPeppers</span><span style="color: rgb(0, 0, 0); font-variant-ligatures: no-common-ligatures;" class="">)</span></div></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">DETAILED DESIGN:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">1. We introduce a new operator :== which works in generic and associated type constraints.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">2. The new operator matches anything that == would match.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">3. The new operator also matches anything that : would match.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">4. If we are in a case where either : or == cannot apply to the protocol on the right of the :== operator, throw an error.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">ALTERNATIVES CONSIDERED:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Put down our peck of pickled peppers picking procedure, then repeat our peck of pickled peppers picking procedure, permuted to preserve the potentiality of protocol passing. Pah.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Charles</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div></span></div></body></html>