[swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

BJ Homer bjhomer at gmail.com
Wed Nov 15 10:25:16 CST 2017

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 ValueContainer protocol on which we might define “flatMap”. (And introducing such a protocol is outside the scope of this proposal.)

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:
Implicit promotion of non-Optional types to Optional types makes it easy to accidentally call the wrong function.
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.
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.
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.
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.
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.

Anyway, I guess the review period ended last night, so we’ll know soon how this turns out.


> On Nov 15, 2017, at 8:39 AM, Tino Heth <2th at gmx.de> wrote:
> Looks like I finally have to draw on drawings... (hope the pictures aren’t considered inappropriate content ;-)
> 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).
> 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:
> <PastedGraphic-2.png>
> https://imgur.com/hy4rel1 <https://imgur.com/hy4rel1>
> There is a transform, which turns an input value (red circle) into a collection (blue basket) of output values (green squares).
> map takes an array of those input values, and stores each result-collection in an array (light blue).
> flatten takes that container, unwraps each sub-collection, and stores its contents together with the other elements.
> 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.
> flatMap just is flatten performed on the output of map.
> 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.
> <PastedGraphic-4.png>
> https://imgur.com/qq95b31 <https://imgur.com/qq95b31>
> 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.
> 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.
> So, that should really be my last word in this discussion — I won’t add an animation or start singing about Optionals ;-)
> - Tino

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171115/80c2e409/attachment.html>

More information about the swift-evolution mailing list