Well, in Swift as in other languages, to filter means to keep the stuff that matches the predicate. So it's not "filter nil" but "filter some." But actually, it's not a filter; it's a flat map operation, since the optional is being unwrapped.<br><br>Also, based on the precedent of "flat map," I think it really should be "filter map" and not "map filter," which would suggest incorrectly that the predicate would be for filtering.<br><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 23, 2017 at 22:38 Howard Lovatt via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">+1 good idea.<div><br></div><div>Re. the naming I would suggest `mapF<font color="#000000" face="Helvetica Neue">ilterNil` since it says what it does and filter, nil, and map are all understood already in Swift. (I have sympathy for people wanting </font>`mapF<font color="#000000" face="Helvetica Neue">ilteringNil`, but Swift chose `filter`.)</font></div><div><font color="#000000" face="Helvetica Neue"><br></font></div><div><font color="#000000" face="Helvetica Neue">The problems I see with `filterMap` are that:</font></div><div><font color="#000000" face="Helvetica Neue"><br></font></div><div><font color="#000000" face="Helvetica Neue"> 1. It sounds like it is a merged `filter` and `map` and therefore you would expect it to have two arguments, one to filter and one to map, i.e. `filterMap<R>(filter: (T) -> Bool, map: (T) -> R) -> [R]`.</font></div><div><font color="#000000" face="Helvetica Neue"> 2. It sounds like it will filter the incoming values (for `nil`, but see 1 above) and then map, i.e. </font><span style="color:rgb(0,0,0);font-family:"Helvetica Neue"">`filterMap<R>(map: (T?) -> R) -> [R]`, note `T?` *not* `R?`.</span></div>
</div><div class="gmail_extra"></div><div class="gmail_extra"><br clear="all"><div><div class="m_-7024355024989951142gmail_signature" data-smartmail="gmail_signature"> -- Howard.<br></div></div></div><div class="gmail_extra">
<br><div class="gmail_quote">On 24 October 2017 at 11:56, BJ Homer 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">I agree with Xiaodi; I like ‘filterMap’ more than ‘filteredMap’. But both are superior to ‘flatMap’ in this context.<br><br><div id="m_-7024355024989951142m_-5168321874247595364AppleMailSignature">-BJ</div><div><div class="m_-7024355024989951142h5"><div><br>On Oct 23, 2017, at 5:22 PM, Max Moiseev <<a href="mailto:moiseev@apple.com" target="_blank">moiseev@apple.com</a>> wrote:<br><br></div><blockquote type="cite"><div>It occurred to me that filteringMap(_:) should be even more descriptive, still conform to the guidelines, although similarly unprecedented and un-googlable.<div><br></div><div>Max<br><div><br><blockquote type="cite"><div>On Oct 23, 2017, at 3:52 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>> wrote:</div><br class="m_-7024355024989951142m_-5168321874247595364Apple-interchange-newline"><div>+1 in general. As to the name: since 'map' is used as a term of art, 'filterMap' seems superior to 'filteredMap', which half follows naming guidelines and half is a term of art; neither is immediately comprehensible but 'filterMap' can be googled and has precedents in other languages.<br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 23, 2017 at 17:24 BJ Homer via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">I strongly agree! In fact, I just started writing up a similar proposal the other day, but hadn’t had time to finish it yet.<div><br></div><div>The current name for this particular filtering variant is not particularly descriptive. It’s certainly not obvious to newcomers that ‘flatMap’ will filter out results. And it’s not true to the existing usage of ‘flatMap' from other languages; you have to really squint at it to see how any “flattening” is happening at all.</div><div><br></div><div>So yes, a big +1 from me. Thanks!</div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><br></div><div>-BJ Homer</div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div><br><blockquote type="cite"><div>On Oct 23, 2017, at 4:15 PM, Max Moiseev via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278Apple-interchange-newline"><div><div style="word-wrap:break-word;line-break:after-white-space">Hi swift-evolution!<div><br></div><div>I would like to propose the following change to the standard library:</div><div><br></div><div>deprecate `Sequence.flatMap<U>(_: (Element) -> U?) -> [U]` and make this functionality available under a new name `Sequence.filteredMap(_:)`.</div><div><br></div><div>The draft is available at <a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95" target="_blank">https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95</a> and is included below for your convenience.</div><div><br></div><div>Max</div><div><br></div><div><h1 style="box-sizing:border-box;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255);margin-top:0px!important">Introduce Sequence.filteredMap(_:)</h1><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><li style="box-sizing:border-box">Proposal: <a href="https://gist.github.com/moiseev/NNNN-filename.md" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none" target="_blank">SE-NNNN</a></li><li style="box-sizing:border-box;margin-top:0.25em">Authors: <a href="https://github.com/moiseev" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none" target="_blank">Max Moiseev</a></li><li style="box-sizing:border-box;margin-top:0.25em">Review Manager: TBD</li><li style="box-sizing:border-box;margin-top:0.25em">Status: <span style="box-sizing:border-box;font-weight:600">Awaiting implementation</span></li></ul><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#introduction" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-introduction" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Introduction</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">We propose to deprecate the controversial version of a <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Sequence.flatMap</code> method and provide the same functionality under a different, and potentially more descriptive, name.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#motivation" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-motivation" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Motivation</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">The Swift standard library currently defines 3 distinct overloads for <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code>:</p><div class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight-source-swift" style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Sequence</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">flatMap</span><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)"><</span>S<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">_</span>: (<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Element</span>) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> S) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> [S.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Element</span>]
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">where</span> S <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">:</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Sequence</span>
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Optional</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">flatMap</span><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)"><</span>U<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">_</span>: (Wrapped) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> U<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">?</span>) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> U<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">?</span>
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Sequence</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">flatMap</span><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)"><</span>U<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">_</span>: (<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Element</span>) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> U<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">?</span>) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> [U]</pre></div><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">The last one, despite being useful in certain situations, can be (and often is) misused. Consider the following snippet:</p><div class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight-source-swift" style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">struct</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">Person</span> {
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">var</span> age<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">:</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Int</span>
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">var</span> name<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">:</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">String</span>
}
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">getAges</span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">people</span></span>: [Person]) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> [<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Int</span>] {
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> people.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">flatMap</span> { <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">$0</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">age</span> }
}</pre></div><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">What happens inside <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">getNames</code> is: thanks to the implicit promotion to <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Optional</code>, the result of the closure gets wrapped into a <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">.some</code>, then immediately unwrapped by the implementation of <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code>, and appended to the result array. All this unnecessary wrapping and unwrapping can be easily avoided by just using <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">map</code> instead.</p><div class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight-source-swift" style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">getAges</span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">people</span></span>: [Person]) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> [<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">Int</span>] {
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> people.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">map</span> { <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">$0</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">age</span> }
}</pre></div><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">It gets even worse when we consider future code modifications, like the one where Swift 4 introduced a <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">String</code>conformance to the <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Collection</code> protocol. The following code used to compile (due to the <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code> overload in question).</p><div class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278highlight-source-swift" style="box-sizing:border-box;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">getNames</span>(<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box"><span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">people</span></span>: [Person]) <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-></span> [<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">String</span>] {
<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">return</span> people.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">flatMap</span> { <span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">$0</span>.<span class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278pl-smi" style="box-sizing:border-box">name</span> }
}</pre></div><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">But it no longer does, because now there is a better overload that does not involve implicit promotion. In this particular case, the compiler error would be obvious, as it would point at the same line where <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code> is used. Imagine however if it was just a <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">let names = people.flatMap { $<a href="http://0.name/" target="_blank">0.name</a> }</code> statement, and the <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">names</code> variable were used elsewhere. The compiler error would be misleading.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#proposed-solution" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-proposed-solution" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Proposed solution</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">We propose to deprecate the controversial overload of <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code> and re-introduce the same functionality under a new name. The name being <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filteredMap(_:)</code> as we believe it best describes the intent of this function.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">For reference, here are the alternative names from other languages:</p><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)"><li style="box-sizing:border-box">Haskell, Idris <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">
mapMaybe :: (a -> Maybe b) -> [a] -> [b]</code></li><li style="box-sizing:border-box;margin-top:0.25em">Ocaml (Core and Batteries)
<code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filter_map : 'a t -> f:('a -> 'b option) -> 'b t</code></li><li style="box-sizing:border-box;margin-top:0.25em">F#
<code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">List.choose : ('T -> 'U option) -> 'T list -> 'U list</code></li><li style="box-sizing:border-box;margin-top:0.25em">Rust
<code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where F: FnMut(Self::Item) -> Option<B></code></li><li style="box-sizing:border-box;margin-top:0.25em">Scala <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">
def collect[B](pf: PartialFunction[A, B]): List[B]</code></li></ul><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#source-compatibility" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-source-compatibility" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Source compatibility</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">Since the old function will still be available (although deprecated) all the existing code will compile, producing a deprecation warning and a fix-it.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#effect-on-abi-stability" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-effect-on-abi-stability" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Effect on ABI stability</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">This is an additive API change, and does not affect ABI stability.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#effect-on-api-resilience" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-effect-on-api-resilience" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Effect on API resilience</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">Ideally, the deprecated <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">flatMap</code> overload would not exist at the time when ABI stability is declared, but in the worst case, it will be available in a deprecated form from a library post-ABI stability.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(234,236,239);color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";background-color:rgb(255,255,255)"><a href="https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#alternatives-considered" class="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278anchor" id="m_-7024355024989951142m_-5168321874247595364m_-3167177071233817278user-content-alternatives-considered" style="box-sizing:border-box;background-color:transparent;color:rgb(3,102,214);text-decoration:none;float:left;padding-right:4px;line-height:1" target="_blank"><u></u><u></u><u></u><u></u></a>Alternatives considered</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">It was attempted in the past to warn about this kind of misuse and do the right thing instead by means of a deprecated overload with a non-optional-returning closure. The attempt failed due to another implicit promotion (this time to <code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">Any</code>).</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255)">The following alternative names for this function were considered:</p><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;color:rgb(36,41,46);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;background-color:rgb(255,255,255);margin-bottom:0px!important"><li style="box-sizing:border-box"><code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">mapNonNil(_:)
</code> Does not communicate what happens to nil’s</li><li style="box-sizing:border-box;margin-top:0.25em"><code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">mapSome(_:)
</code> Reads more like «map some elements of the sequence, but not the others» rather than «process only the ones that produce an Optional.some»</li><li style="box-sizing:border-box;margin-top:0.25em"><code style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(27,31,35,0.0470588);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">filterMap(_:)</code>
Does not really follow the naming guidelines and doesn’t seem to be common enough to be considered a term of art.</li></ul><div><br></div></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></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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>
</div></blockquote></div><br></div></div></blockquote></div></div></div><br>_______________________________________________<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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>