<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I think we understand each other; we just disagree. If you believe that it makes intuitive sense to talk about “flattening” a sequence of optionals, then the current name perhaps makes sense. If you don’t think so, then the “flatten” name is awkward in this context. I don’t think most Swift users would find it intuitive, as Optional does not conform to Sequence, and there is no <font face="Menlo" class="">ValueContainer</font> protocol on which we might define “flatMap”. (And introducing such a protocol is outside the scope of this proposal.)<div class=""><br class=""></div><div class="">Even if “flatMap” does make conceptual sense to you on a sequence of Optionals, though, the API as it exists right now still has the other problems mentioned in the proposal and throughout this thread:</div><div class=""><ol class=""><li class="">Implicit promotion of non-Optional types to Optional types makes it easy to accidentally call the wrong function.</li><li class="">Discoverability: Users looking to filter out ‘nil’ values have to know about something that does not say “filter”. Most new Swift users do not naturally discover this functionality.</li><li class="">Fragility: Adding “Collection” conformance to a type caused source incompatibility (as shown in the original proposal). In general, adding conformances should not break existing code.</li><li class="">Fragility: Changing a type from Optional to non-Optional (or vice versa) should not silently change behavior. But in this case, because of implicit optional promotion, it can.</li><li class="">Non-obvious behavior: In my experience, new Swift users do not intuitively understand what it means to “flatMap” a sequence of optionals, and could not intuitively understand the meaning of “flatten” in this context.</li></ol></div><div class="">We can make Swift a more intuitive language by not pretending that Optionals are Sequences when they’re really not, and we can make it a more robust language by avoiding ambiguity between different versions of Sequence.flatMap in the presences of subtle type changes.</div><div class=""><br class=""></div><div class="">Anyway, I guess the review period ended last night, so we’ll know soon how this turns out.</div><div class=""><br class=""></div><div class="">-BJ</div><div class=""><br class=""><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Nov 15, 2017, at 8:39 AM, Tino Heth <<a href="mailto:2th@gmx.de" class="">2th@gmx.de</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Looks like I finally have to draw on drawings... (hope the pictures aren’t considered inappropriate content ;-)<div class=""><br class=""></div><div class="">But after all, it might be the best way to convey my point anyways: I’m not thinking in terms of type names (why should it only be possible to flatten a „Sequence“? Many people associate this operation with lists, which aren’t common in Swift at all) or implementation details (neither Optional nor Sequence actually has a flatten-method).</div><div class="">Instead, I tend to look at the easiest way to explain how to get from input to output, so here is what I have in my mind when I speak about Sequence-Sequence flatmap:<br class=""><div class=""><br class=""><div class=""><span id="cid:BAC01AA1-C5B0-43BC-BC66-0A879FE110C3@fritz.box"><PastedGraphic-2.png></span></div><div class=""></div><div class=""><a href="https://imgur.com/hy4rel1" class="">https://imgur.com/hy4rel1</a></div><div class=""><br class=""></div><div class="">There is a transform, which turns an input value (red circle) into a collection (blue basket) of output values (green squares).</div><div class="">map takes an array of those input values, and stores each result-collection in an array (light blue).</div><div class="">flatten takes that container, unwraps each sub-collection, and stores its contents together with the other elements.</div><div class="">Note that empty collections aren’t skipped or removed — they just have nothing that they could contribute to the final result, so no trace of them is left.</div><div class="">flatMap just is flatten performed on the output of map.</div><div class=""><br class=""></div><div class="">Now, Optionals… I could simply say „think of those as an array with a maximal size of one“ — but because there’s really no fundamental difference, I just copied the sequence-illustration, and changed one tiny bit: The transformation doesn’t return multiple items now, so that the blue basket can act as representation for an Optional.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><span id="cid:3A077B2B-08A9-46DA-9766-48ACE045556C@fritz.box"><PastedGraphic-4.png></span></div><div class=""><a href="https://imgur.com/qq95b31" class="">https://imgur.com/qq95b31</a></div><div class=""><br class=""></div></div></div><div class="">So conceptionally, both overrides are equivalent: The transformation always produces something — an Optional, and that can contain a value, or it can be empty, just like an array.</div><div class="">You also see that the flatten step really does what it says: It removes one layer of objects, and leaves a flush surface without gaps.</div><div class=""><br class=""></div><div class="">So, that should really be my last word in this discussion — I won’t add an animation or start singing about Optionals ;-)</div><div class=""><br class=""></div><div class="">- Tino</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""></div></div></body></html>