<div dir="ltr">Is it the intention that `associatedtype Filtered : Sequence` once recursive protocol constraints are supported? Can it be `associatedtype Filtered : Collection`?<div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 23, 2017 at 2:37 PM, Ben Cohen via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</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"><div><br></div><div>Hi swift evolution,</div><div><br></div><div>The following is a proposal that came off the back of the discussions accepting the recent Dictionary proposal.</div><div><br></div><div>It is small but has source-breaking implications so would be good to get in for the 4.0 release.</div><div><br></div><div>Online copy here: <a href="https://github.com/airspeedswift/swift-evolution/blob/804d24e8950de98dd6af146b6367043e2f5072a8/proposals/NNNN-filter-range-replaceable.md" target="_blank">https://github.com/<wbr>airspeedswift/swift-evolution/<wbr>blob/<wbr>804d24e8950de98dd6af146b636704<wbr>3e2f5072a8/proposals/NNNN-<wbr>filter-range-replaceable.md</a></div><div><br></div><div><br></div><div><br></div><div><h1 id="m_-5399143482839882268change--code-filter--code--to-return-an-associated-type" style="box-sizing:border-box;font-size:2.25em;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.2;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255);margin-top:0px!important">Change <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:24.479999542236328px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter</code> to return an associated type</h1><ul style="box-sizing:border-box;padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)"><li style="box-sizing:border-box">Proposal: <a style="box-sizing:border-box;background-color:transparent;color:rgb(65,131,196);text-decoration:none">SE-NNNN</a></li><li style="box-sizing:border-box"><ins id="m_-5399143482839882268firstdiff" style="box-sizing:border-box;display:inline-block;text-decoration:none!important;border:none!important;background-image:none!important;background-position:initial initial!important;background-repeat:initial initial!important"></ins>Authors: <a href="https://github.com/airspeedswift" style="box-sizing:border-box;background-color:transparent;color:rgb(65,131,196);text-decoration:none" target="_blank">Ben Cohen</a></li><li style="box-sizing:border-box">Review Manager: TBD</li><li style="box-sizing:border-box">Status: <strong style="box-sizing:border-box">Awaiting review</strong></li></ul><h2 id="m_-5399143482839882268introduction" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Introduction</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">This proposal changes the <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter</code> operation on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence</code> to return an associated type, and adds a default implementation to <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">RangeReplaceableCollection</code> <wbr>to return the same type as the filtered collection.</p><h2 id="m_-5399143482839882268motivation" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Motivation</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">The recently accepted <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0165-dic%0A%20t.md" style="box-sizing:border-box;background-color:transparent;color:rgb(65,131,196);text-decoration:none" target="_blank">SE-165</a> introduced a version of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter</code> on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code> that returned a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code>. This had both performance and useability benefits: in most cases, a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code> is what the user wanted from the filter, and creating one directly from the filter operation is much more efficient than first creating an array then creating a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code> from it.</p><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">However, this does result in some inconsistencies. Users may be surprised that this one specific collection returns <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Self</code>, while other collections that would benefit from the same change still return <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">[Element]</code>. And some collections, such as <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">String</code>, might also benefit from usability and performance win similar to <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code>. Additionally, these wins will be lost in generic code – if you pass a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code> into an algorithm that takes a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence</code>, then when you filter it, you will still get an <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Array</code>.</p><h2 id="m_-5399143482839882268proposed-solution" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Proposed solution</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">The existing protocol requirement on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter</code> will be changed to return an associated type, <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Filtered</code>. The extension providing a default implementation will remain as-is, resulting in an inferred value for <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Filtered</code> of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">[Element]</code>. <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dic<wbr>tionary</code> will automatically infer a filtered type of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Dictionary</code> as a result of this change.</p><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">A default implementation on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">RangeReplaceableCollection</code> <wbr>will be provided, using <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">init()</code> and <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">append(_:)</code>, so all range-replaceable collections will have a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Filtered</code> of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Self</code>. Per <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0163-string-revision-1.md" style="box-sizing:border-box;background-color:transparent;color:rgb(65,131,196);text-decoration:none" target="_blank">SE-163</a>, this will include <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">String</code>.</p><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Note, many sequences (for example, strides or ranges), cannot represent a filtered <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">self</code> as <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Self</code> and will continue to return an array. If this is a performance problem, <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">lazy</code> remains a good solution.</p><h2 id="m_-5399143482839882268detailed-design" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Detailed design</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Add a <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Filtered</code> associated type to <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence</code>, and change the requirement to return it:</p><pre style="box-sizing:border-box;overflow:auto;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;line-height:1.45;padding:16px;background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51,51,51);height:358px"><code class="m_-5399143482839882268swift m_-5399143482839882268hljs" style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;padding:0.5em;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:0px;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto"><span class="m_-5399143482839882268hljs-class" style="box-sizing:border-box"><span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">protocol</span> <span class="m_-5399143482839882268hljs-title" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Sequence</span> </span>{
  associatedtype <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Filtered</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// Returns an filtered sequence containing, in order, the elements of the </span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// sequence that satisfy the given predicate.</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// In this example, `filter` is used to include only names shorter than</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// five characters.</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///     let cast = [&quot;Vivien&quot;, &quot;Marlon&quot;, &quot;Kim&quot;, &quot;Karl&quot;]</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///     let shortNames = cast.filter { $0.characters.count &lt; 5 }</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///     print(shortNames)</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///     // Prints &quot;[&quot;Kim&quot;, &quot;Karl&quot;]&quot;</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// - Parameter isIncluded: A closure that takes an element of the</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///   sequence as its argument and returns a Boolean value indicating</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">///   whether the element should be included in the returned sequence.</span>
  <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">/// - Returns: An array of the elements that `includeElement` allowed.</span>
  <span class="m_-5399143482839882268hljs-function" style="box-sizing:border-box"><span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">func</span> <span class="m_-5399143482839882268hljs-title" style="box-sizing:border-box;color:rgb(153,0,0);font-weight:bold">filter</span><span class="m_-5399143482839882268hljs-params" style="box-sizing:border-box">(
    <span class="m_-5399143482839882268hljs-number" style="box-sizing:border-box;color:rgb(0,128,128)">_</span> isIncluded: <span class="m_-5399143482839882268hljs-params" style="box-sizing:border-box">(Iterator.Element)</span></span></span> <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">throws</span> -&gt; <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Bool</span>
  ) <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">rethrows</span> -&gt; <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Filtered</span>
}</code></pre><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Add a default implementation of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter</code> to <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">RangeReplaceableC<wbr>ollection</code> returning <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Self</code>:</p><pre style="box-sizing:border-box;overflow:auto;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;line-height:1.45;padding:16px;background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51,51,51);height:208px"><code class="m_-5399143482839882268swift m_-5399143482839882268hljs" style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;padding:0.5em;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:0px;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto"><span class="m_-5399143482839882268hljs-class" style="box-sizing:border-box"><span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">extension</span> <span class="m_-5399143482839882268hljs-title" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">RangeReplaceableCollection</span> </span>{
    <span class="m_-5399143482839882268hljs-function" style="box-sizing:border-box"><span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">func</span> <span class="m_-5399143482839882268hljs-title" style="box-sizing:border-box;color:rgb(153,0,0);font-weight:bold">filter</span><span class="m_-5399143482839882268hljs-params" style="box-sizing:border-box">(<span class="m_-5399143482839882268hljs-number" style="box-sizing:border-box;color:rgb(0,128,128)">_</span> isIncluded: <span class="m_-5399143482839882268hljs-params" style="box-sizing:border-box">(Iterator.Element)</span></span></span> <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">throws</span> -&gt; <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Bool</span>) <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">rethrows</span> -&gt; <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Self</span> {
        <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">var</span> result = <span class="m_-5399143482839882268hljs-type" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">Self</span>()
        <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">for</span> element <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">in</span> <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">self</span> {
            <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">if</span> <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">try</span> isIncluded(element) {
                result.append(element)
            }
        }
        <span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">return</span> result
    }
}</code></pre><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Specific concrete collections may choose to implement a faster version, but this is an implementation detail.</p><h2 id="m_-5399143482839882268source-compatibility" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Source compatibility</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">This change is subtly source breaking. In most cases users will not notice. They may be be relying on an array being returned (albeit often in order to then transform it back into the original type), but this version will still be available (via the extension on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence</code>) and will be called if forced through type context. The only code that will break is if this operation spans multple lines:</p><pre style="box-sizing:border-box;overflow:auto;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;margin-top:0px;margin-bottom:16px;line-height:1.45;padding:16px;background-color:rgb(248,248,248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;color:rgb(51,51,51);height:88px"><code class="m_-5399143482839882268swift m_-5399143482839882268hljs" style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;padding:0.5em;margin:0px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:0px;display:block;overflow-x:auto;line-height:inherit;word-wrap:normal;height:auto"><span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">// filtered used to be [Character], now String</span>
<span class="m_-5399143482839882268hljs-keyword" style="box-sizing:border-box;font-weight:bold">let</span> filtered = <span class="m_-5399143482839882268hljs-string" style="box-sizing:border-box;color:rgb(221,17,68)">&quot;abcd&quot;</span>.<span class="m_-5399143482839882268hljs-built_in" style="box-sizing:border-box;color:rgb(0,134,179)">filter</span> { $<span class="m_-5399143482839882268hljs-number" style="box-sizing:border-box;color:rgb(0,128,128)">0</span> == <span class="m_-5399143482839882268hljs-string" style="box-sizing:border-box;color:rgb(221,17,68)">&quot;a&quot;</span> }
useArray(filtered) <span class="m_-5399143482839882268hljs-comment" style="box-sizing:border-box;color:rgb(153,153,136);font-style:italic">// won&#39;t compile</span></code></pre><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Because of this, the new implementation of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">RangeReplaceableCollection.<wbr>filter</code> will only be available in Swift 4.</p><h2 id="m_-5399143482839882268effect-on-abi-stability" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Effect on ABI stability</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">This change will affect the ABI of <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence</code> and needs to be made before declaring ABI stability.</p><h2 id="m_-5399143482839882268effect-on-api-resilience" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Effect on API resilience</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">N/A</p><h2 id="m_-5399143482839882268alternatives-considered" style="box-sizing:border-box;margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;color:rgb(51,51,51);padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);font-family:helvetica,arial,freesans,clean,sans-serif;background-color:rgb(255,255,255)">Alternatives considered</h2><p style="box-sizing:border-box;margin:0px 0px 16px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255)">Status-quo. There are benefits to the consistency of always returning <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">[Element]</code>.</p><div style="box-sizing:border-box;margin-top:0px;margin-right:0px;margin-left:0px;color:rgb(51,51,51);font-family:helvetica,arial,freesans,clean,sans-serif;font-size:12.799999237060547px;background-color:rgb(255,255,255);margin-bottom:0px!important">It could be worthwhile to make a similar change to <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">map</code>, but this is beyond the capabilities of the current generics system because <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">map</code> does not preserve the element type (more specifically, you cannot express a type that is <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Self</code> except with a different <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Element</code> in order to provide the default implementation on <code style="box-sizing:border-box;font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:10.880000114440918px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">RangeReplaceableCollection</code>)<wbr>.</div></div></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div></div>