<div dir="ltr">I like the idea. A few notes on naming:<div>– <font face="monospace, monospace">minIndex</font> is somewhat confusing to me (it sounds like it's getting the minimum index, i.e. indices.minElement()). How about <font face="monospace, monospace">indexOfMin()</font><font face="arial, helvetica, sans-serif"> or </font><font face="monospace, monospace">indexOfMinElement()</font>?</div><div>– <font face="monospace, monospace">minmax()</font> also doesn't read very well to me, plus it should technically be <font face="monospace, monospace">minMax()</font> which is kinda ugly. Perhaps <font face="monospace, monospace">limits()</font><font face="arial, helvetica, sans-serif"> or </font><font face="monospace, monospace">extrema()</font><font face="arial, helvetica, sans-serif">? The latter would be the most correct mathematically. For the index form that</font><font face="arial, helvetica, sans-serif"> would give e.g. </font><font face="monospace, monospace">indicesOfExtrema()</font><font face="times new roman, serif">.</font></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 17, 2016 at 4:42 PM, Nate Cook via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><span class=""><div><br></div><div>On Apr 17, 2016, at 8:46 AM, plx via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><div>I like the idea. It worries me a bit if the general recipe for such situations is to add dedicated-purpose methods like `_customIndexOfMinComparableElement` (etc.) to standard-library protocols; it *will* work, but is only going to work for the methods that get such treatment.</div></div></blockquote><div><br></div></span><div>Agreed! I'm not sure if that's part of the generics manifesto or not, but it'd be great to have conditionally applied dynamically dispatched methods for cases like this.</div><span class=""><br><blockquote type="cite"><div><div>If it were feasible, I’d *greatly* prefer having some more-general way to (conditionally?) add overridable methods to a protocol, e.g.:</div><div><br></div><div> // made-up declaration, all declared methods below are now overridable</div><div> // on suitable types</div><div> overridable extension Collection where Iterator.Element: Comparable {</div><div> </div><div> func min() -> Iterator.Element? </div><div><br></div><div> }</div><div><br></div><div>…but am not sure that’s even realistically possible.</div><div><br></div><div>The reason I bring it up is that I’d hope that `indexOf`, `contains`, and also `upperBound`/`lowerBound` would merit a similar treatment to that proposed here for min, max, and minmax (if not already given such; if they get added to standard-library; etc.).</div></div></blockquote><div><br></div></span><div>The customization points in the proposal are modeled after the two existing ones in the standard library for `contains` and `index(of:)`. You can see them here:</div><div><br></div><div><a href="https://github.com/apple/swift/blob/master/stdlib/public/core/Sequence.swift#L190" target="_blank">https://github.com/apple/swift/blob/master/stdlib/public/core/Sequence.swift#L190</a></div><div><a href="https://github.com/apple/swift/blob/master/stdlib/public/core/Collection.swift#L184" target="_blank">https://github.com/apple/swift/blob/master/stdlib/public/core/Collection.swift#L184</a></div><div><div class="h5"><br><blockquote type="cite"><div><div>Moving on, wrt these min/max elements themselves: I think any expectation about *which* index gets returned should be document—either no such expectation in general, or a specific expectation, or that each concrete collection should document the expectation, etc.—because for the minIndex/maxIndex methods different approaches can yield different results.</div><div><br></div><div>EG: consider an order-maintaining collection that has contents ~ `[1,1,1,2,2,2,3,3,3]`. There are multiple candidates for both `minIndex` and `maxIndex`.</div><div><br></div><div>I don’t have a strong opinion on what the right preference would be here, but I think whatever the behavior winds up being should be at least documented.</div><div><br></div><div>Finally, FWIW if more of these semi-hidden methods become something exposed to users (as “advanced” options, perhaps, but still) I think replacing `??` with something like</div><div><br></div><div> enum AdvancedCustomizationPointResult<T> {</div><div> case NotCustomized // like `nil` for ??</div><div> case NoResult // like `Optional(nil)` for ??</div><div> case Result(T) // like `Optional(T)` for ??</div><div> }</div><div><br></div><div>…might be worth considering (except with a better name than that). I’m not trying to backdoor optional protocol methods or anything, it just seems advisable to more-explicitly represent the intent (?? certainly works but feels a bit obscure).</div><br><div><blockquote type="cite"><div>On Apr 17, 2016, at 1:44 AM, Nate Cook via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><div style="word-wrap:break-word"><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)">Hello all,</span></font><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)"><br></span></font></div><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)">Attached is a draft of a proposal to expand the min and max sequence APIs to better handle collections and to support future sorted sequences/collections. The proposal </span></font><a href="https://gist.github.com/natecook1000/d51267a6cf9e9463b9387bced4c65b16" target="_blank">is in a gist here</a><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)"> and inlined below—would love to hear any comments or feedback before submitting the proposal.</span></font></div><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)"><br></span></font></div><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)">Nate</span></font></div><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)"><br></span></font></div><div><font face="Helvetica, arial, sans-serif"><span style="background-color:rgb(255,255,255)"><br></span></font><h1 style="margin-right:0px;margin-bottom:10px;margin-left:0px;padding:0px;font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255);margin-top:0px!important">Proposal: Expanded min/max algorithms</h1><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">This proposal would expand on the <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code> sequence methods to add methods that return the corresponding index for a collection, efficiently find the minimum and maximum elements or indices at the same time, and provide extension points for sorted collections to provide all these results more efficiently.</p><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)"><strong>Related Bugs:</strong> <a href="https://bugs.swift.org/browse/SR-889" style="color:rgb(65,131,196)" target="_blank">SR-889</a> and <a href="https://bugs.swift.org/browse/SR-890" style="color:rgb(65,131,196)" target="_blank">SR-890</a></p><h2 style="margin:20px 0px 10px;padding:0px;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204,204,204);font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Motivation</h2><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">The <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Sequence</code> protocol currently offers <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code> methods that return the minimum and maximum elements of a sequence or collection. Unfortunately, there are applications where these methods do not provide enough flexibility to be useful.</p><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">First, if the user of a collection wants not just to get the minimum value but also to operate on it in some way (e.g., mutation or just accessing it multiple times), she would need the index of the minimum element. The current APIs don't support that, so she would need to write her own.</p><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">Second, the writer of a sorted collection is currently unable to provide efficient responses to the <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code> methods when used in a generic context, even though these should be O(1) operations. Just like <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Set</code> can respond quickly to <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">contains(_:)</code> even in a generic context, so too should new sorted collections be able to optimize their responses.</p><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">Finally, getting the minimum and maximum elements (or indices) of a collection or sequence currently requires calling both <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code>. With two calls, every element is iterated and compared twice. When you need both results, finding both the minimum and the maximum at the same time is more efficient, requiring only a single pass and 25% fewer comparisons.</p><h2 style="margin:20px 0px 10px;padding:0px;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204,204,204);font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Proposed solution</h2><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">This proposal has three parts:</p><ol style="margin:15px 0px;padding-left:30px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)"><li style="margin:0px"><p style="margin:0px 0px 15px">Adding <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">minIndex()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">maxIndex()</code> methods to <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Collection</code> that return the index of the minimum and maximum elements, respectively.</p><div><pre style="margin-top:0.5em;margin-bottom:0.5em;background-color:rgb(245,242,240);border:1px solid rgb(204,204,204);font-size:13px;line-height:1.5;overflow:auto;padding:1em;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal"><code style="margin:0px;padding:0px;border:none;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-image:none;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5"><span style="margin-top:0px;color:rgb(0,119,170)">let</span> numbers <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">=</span> <span style="color:rgb(153,153,153)">[</span><span style="color:rgb(153,0,85)">30</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(153,0,85)">40</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(153,0,85)">10</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(153,0,85)">20</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(153,0,85)">60</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(153,0,85)">50</span><span style="color:rgb(153,153,153)">]</span>
<span style="color:rgb(0,119,170)">if</span> <span style="color:rgb(0,119,170)">let</span> i <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">=</span> numbers<span style="color:rgb(153,153,153)">.</span><span style="color:rgb(221,74,104)">minIndex</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(221,74,104)">print</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">"<span style="margin-top:0px"><span style="margin-top:0px;color:rgb(238,153,0)">\(</span>i<span style="color:rgb(238,153,0)">)</span></span>: <span><span style="margin-top:0px;color:rgb(238,153,0)">\(</span>numbers<span style="color:rgb(153,153,153)">[</span>i<span style="color:rgb(153,153,153)">]</span><span style="color:rgb(238,153,0)">)</span></span>"</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(112,128,144)">// 2: 10</span>
<span style="color:rgb(153,153,153)">}</span></code></pre></div></li><li style="margin:0px"><p style="margin:0px 0px 15px">Adding <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">minmax()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">minmaxIndices()</code> methods to <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Sequence</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Collection</code>, respectively, to calculate the values (or indices) of the minimum and maximum elements simultaneously.</p><div><pre style="margin-top:0.5em;margin-bottom:0.5em;background-color:rgb(245,242,240);border:1px solid rgb(204,204,204);font-size:13px;line-height:1.5;overflow:auto;padding:1em;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal"><code style="margin:0px;padding:0px;border:none;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-image:none;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5"><span style="margin-top:0px;color:rgb(0,119,170)">if</span> <span style="color:rgb(0,119,170)">let</span> result <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">=</span> numbers<span style="color:rgb(153,153,153)">.</span><span style="color:rgb(221,74,104)">minmax</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">// result == (minimum: 10, maximum: 60)</span>
<span style="color:rgb(112,128,144)">// ...</span>
<span style="color:rgb(153,153,153)">}</span>
<span style="color:rgb(0,119,170)">if</span> <span style="color:rgb(0,119,170)">let</span> i <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">=</span> numbers<span style="color:rgb(153,153,153)">.</span><span style="color:rgb(221,74,104)">minmaxIndices</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">// i == (minimum: 2, maximum: 4)</span>
<span style="color:rgb(221,74,104)">print</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">"<span style="margin-top:0px"><span style="margin-top:0px;color:rgb(238,153,0)">\(</span>i<span style="color:rgb(153,153,153)">.</span>minimum<span style="color:rgb(238,153,0)">)</span></span>: <span><span style="margin-top:0px;color:rgb(238,153,0)">\(</span>numbers<span style="color:rgb(153,153,153)">[</span>i<span style="color:rgb(153,153,153)">.</span>minimum<span style="color:rgb(153,153,153)">]</span><span style="color:rgb(238,153,0)">)</span></span>"</span><span style="color:rgb(153,153,153)">)</span>
<span style="color:rgb(153,153,153)">}</span></code></pre></div></li><li style="margin:0px"><p style="margin:0px 0px 15px">Adding customization points for sequences and collections that can offer more efficient results: <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">_customMinComparableElement()</code>/<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">_customMaxComparableElement()</code> for <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Sequence</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">_customIndexOfMinComparableElement()</code>/<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">_customIndexOfMaxComparableElement()</code>for <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Collection</code>.</p></li></ol><h2 style="margin:20px 0px 10px;padding:0px;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204,204,204);font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Detailed design</h2><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">The following methods would be added to the visible public APIs of <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Sequence</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Collection</code> as default implementations.</p><div style="font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)"><pre style="margin-top:0.5em;margin-bottom:0.5em;background-color:rgb(245,242,240);border:1px solid rgb(204,204,204);font-size:13px;line-height:1.5;overflow:auto;padding:1em;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal"><code style="margin:0px;padding:0px;border:none;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-image:none;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5"><span style="color:rgb(0,119,170)">extension</span> <span style="color:rgb(102,153,0)">Sequence</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">/// Returns the minimum and maximum values of `self`, using </span>
<span style="color:rgb(112,128,144)">/// `isOrderedBefore` to compare elements, or `nil` if the sequence</span>
<span style="color:rgb(112,128,144)">/// has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minmax</span><span style="color:rgb(153,153,153)">(</span>@noescape isOrderedBefore isOrderedBefore<span style="color:rgb(153,153,153)">:</span>
<span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">throws</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Bool</span>
<span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">rethrows</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">min</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">max</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span>
<span style="color:rgb(0,119,170)">extension</span> <span style="color:rgb(102,153,0)">Sequence</span> <span style="color:rgb(0,119,170)">where</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Comparable</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">/// Returns the minimum and maximum values of `self`, or `nil` </span>
<span style="color:rgb(112,128,144)">/// if the sequence has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minmax</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">min</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">max</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span>
<span style="color:rgb(0,119,170)">extension</span> <span style="color:rgb(102,153,0)">Collection</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the minimum element of `self`, using </span>
<span style="color:rgb(112,128,144)">/// `isOrderedBefore` to compare elements, or `nil` if the</span>
<span style="color:rgb(112,128,144)">/// collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minIndex</span><span style="color:rgb(153,153,153)">(</span>@noescape isOrderedBefore isOrderedBefore<span style="color:rgb(153,153,153)">:</span>
<span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">throws</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Bool</span>
<span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">rethrows</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the maximum element of `self`, using </span>
<span style="color:rgb(112,128,144)">/// `isOrderedBefore` to compare elements, or `nil` if the</span>
<span style="color:rgb(112,128,144)">/// collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">maxIndex</span><span style="color:rgb(153,153,153)">(</span>@noescape isOrderedBefore isOrderedBefore<span style="color:rgb(153,153,153)">:</span>
<span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">throws</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Bool</span>
<span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">rethrows</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the indices of the minimum and maximum elements of `self`, </span>
<span style="color:rgb(112,128,144)">/// using `isOrderedBefore` to compare elements, or `nil` if the</span>
<span style="color:rgb(112,128,144)">/// collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minmaxIndices</span><span style="color:rgb(153,153,153)">(</span>@noescape isOrderedBefore isOrderedBefore<span style="color:rgb(153,153,153)">:</span>
<span style="color:rgb(153,153,153)">(</span><span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">,</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">throws</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Bool</span>
<span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(0,119,170)">rethrows</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(153,153,153)">(</span>minIndex<span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(153,153,153)">,</span> maxIndex<span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(153,153,153)">)</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span>
<span style="color:rgb(0,119,170)">extension</span> <span style="color:rgb(102,153,0)">Collection</span> <span style="color:rgb(0,119,170)">where</span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Comparable</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the minimum element of `self`, or `nil` </span>
<span style="color:rgb(112,128,144)">/// if the collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minIndex</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the maximum element of `self`, or `nil` </span>
<span style="color:rgb(112,128,144)">/// if the collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">maxIndex</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the indices of the minimum and maximum elements of `self`, </span>
<span style="color:rgb(112,128,144)">/// or `nil` if the collection has no elements.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">minmaxIndices</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(153,153,153)">(</span>minIndex<span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(153,153,153)">,</span> maxIndex<span style="color:rgb(153,153,153)">:</span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(153,153,153)">)</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span></code></pre></div><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">The customization points would be added to <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Sequence</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">Collection</code> as protocol requirements, along with default implementations that return <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">nil</code>. The existing <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code>and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code> methods would be updated to call the corresponding methods before iterating over the entire sequence.</p><div style="font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)"><pre style="margin-top:0.5em;margin-bottom:0.5em;background-color:rgb(245,242,240);border:1px solid rgb(204,204,204);font-size:13px;line-height:1.5;overflow:auto;padding:1em;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal"><code style="margin:0px;padding:0px;border:none;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-image:none;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5">protocol <span style="color:rgb(102,153,0)">Sequence</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">// ...</span>
<span style="color:rgb(112,128,144)">/// Returns the minimum element as `Optional(element)` or `Optional(nil)`</span>
<span style="color:rgb(112,128,144)">/// if the sequence has no elements. The uncustomized version returns</span>
<span style="color:rgb(112,128,144)">/// `nil`.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">_customMinComparableElement</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the maximum element as `Optional(element)` or `Optional(nil)`</span>
<span style="color:rgb(112,128,144)">/// if the sequence has no elements. The uncustomized version returns</span>
<span style="color:rgb(112,128,144)">/// `nil`.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">_customMaxComparableElement</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Iterator</span><span style="color:rgb(153,153,153)">.</span><span style="color:rgb(102,153,0)">Element</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span>
protocol <span style="color:rgb(102,153,0)">Collection</span> <span style="color:rgb(153,153,153)">{</span>
<span style="color:rgb(112,128,144)">// ...</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the minimum element as `Optional(index)` or</span>
<span style="color:rgb(112,128,144)">/// `Optional(nil)` if the sequence has no elements. The uncustomized </span>
<span style="color:rgb(112,128,144)">/// version returns `nil`.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">_customIndexOfMinComparableElement</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(112,128,144)">/// Returns the index of the maximum element as `Optional(index)` or</span>
<span style="color:rgb(112,128,144)">/// `Optional(nil)` if the sequence has no elements. The uncustomized </span>
<span style="color:rgb(112,128,144)">/// version returns `nil`.</span>
<span style="color:rgb(0,119,170)">func</span> <span style="color:rgb(221,74,104)">_customIndexOfMaxComparableElement</span><span style="color:rgb(153,153,153)">(</span><span style="color:rgb(153,153,153)">)</span> <span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">-</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">></span> <span style="color:rgb(102,153,0)">Index</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span><span style="color:rgb(166,127,89);background-color:rgba(255,255,255,0.498039);background-position:initial initial;background-repeat:initial initial">?</span>
<span style="color:rgb(153,153,153)">}</span></code></pre></div><h4 style="margin:20px 0px 10px;padding:0px;font-size:16px;font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Minmax Algorithm</h4><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">The <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">minmax()</code> algorithm finds the minimum and maximum elements of a sequence in one pass more efficiently than consecutive calls to <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">min()</code> and <code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;border:1px solid rgb(234,234,234);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">max()</code>. This optimization comes from iterating over a sequence two elements at a time. </p><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">In each iteration, two consecutive elements are compared with each other. Only the lesser element could be a minimum for the whole sequence, so it is compared with the current minimum, while only the greater element could be a maximum, so it is compared with the current maximum. This works out to 3 comparisons for every 2 elements vs. 2 comparisons for every element when the minimum and maximum are found individually.</p><h2 style="margin:20px 0px 10px;padding:0px;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204,204,204);font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Impact on existing code</h2><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">As new APIs these should have no effect on existing code.</p><h2 style="margin:20px 0px 10px;padding:0px;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204,204,204);font-family:Helvetica,arial,sans-serif;background-color:rgb(255,255,255)">Alternatives considered</h2><p style="margin:15px 0px;font-family:Helvetica,arial,sans-serif;font-size:14px;background-color:rgb(255,255,255)">None.</p></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></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></div></div><br>_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>