<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello, all! This SequenceType-implemented flatMap recently caused some confusion on my team:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]</font></div></blockquote><div class=""><br class=""></div><div class="">I’m a big fan of this operator in various functional libraries, but I admit I was a bit surprised to see the “flatMap” terminology appear in the Swift stdlib in the first place—its naming is certainly a notch obscure!<br class=""></div><div class=""><br class=""></div><div class="">From the reactions of teammates in code reviews involving these methods, there was a significant difference in comprehensibility between the <font face="Menlo" class="">Element -> [T]</font> variant and the <span style="font-family: Menlo;" class="">Element -> T?</span> variant. The former was easily explained by “it’s a map, followed by a flatten,” whereas the same explanation failed in the latter case.</div><div class=""><br class=""></div><div class="">I expect that the inspiration came from Scala, where the equivalent definition has a transformer essentially of type <font face="Menlo" class="">Element -> GeneratorType<T></font>; separately, their optionals are implicitly convertible to (their equivalent of) <span style="font-family: Menlo;" class="">GeneratorType</span>. So, in the end, in Scala, you can effectively flatMap with an <span style="font-family: Menlo;" class="">Element -> T?</span> transformer.</div><div class=""><br class=""></div><div class="">But <font face="Menlo" class="">Optional</font> doesn’t implement <font face="Menlo" class="">GeneratorType</font>, and I’d (weakly) argue that it shouldn’t. And if we think about <font face="Menlo" class="">flatMap</font> in the context of a monadic bind (I do, anyway!), it’s especially surprising that the transformer is operating in a different monadic context (<font face="Menlo" class="">Optional</font>) than the receiver (<font face="Menlo" class="">SequenceType</font>). Unless we made <font face="Menlo" class="">Optional</font> adopt <font face="Menlo" class="">SequenceType</font>, in which case we could consider the bind to be happening in that context.</div><div class=""><br class=""></div><div class="">In conclusion, I argue that this overload is confusing both to folks unfamiliar with FP (because it doesn’t feel like Optionals can be flattened) and to folks familiar with FP (because it implies binding across monadic contexts).</div><div class=""><br class=""></div><div class="">~</div><div class=""><br class=""></div><div class="">In terms of what to do instead: I do think that this is a useful method, and I’d like to keep this functionality easily accessible! Two ideas:</div><div class=""><br class=""></div><div class="">1. We expose a separate operator like:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">extension SequenceType where Generator.Element: OptionalType {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func filterNils() -> [Generator.Element.Wrapped]</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">// To deal with limitations on protocol extension type restriction:</font></div><div class=""><font face="Menlo" class="">protocol OptionalType {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>typealias Wrapped</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func flatMap<Result>(@noescape f: Wrapped -> Result?) -> Result?</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class="">extension Optional: OptionalType {}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div></blockquote><div class="">Clients would do <font face="Menlo" class="">myArray.map(optionalReturningTransform).filterNils()</font>. There would be some performance impact from the intermediate array.</div><div class=""><br class=""></div>2. We give the foo variant a more specific name, e.g. <font face="Menlo" class="">mappedArrayFilteringNils</font> etc. Naming this is tricky (which probably implies it should be decomposed?).</body></html>