> On Oct 24, 2017, at 1:57 AM, David Hart via swift-evolution > <swift-evolution@swift.org> wrote: > > I also cast my vote for filterMap. It’s concise, understandable and is kind > of a term of art also.
+1. This seems like the best option to me. > >> On 24 Oct 2017, at 02:56, BJ Homer via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> I agree with Xiaodi; I like ‘filterMap’ more than ‘filteredMap’. But both >> are superior to ‘flatMap’ in this context. >> >> -BJ >> >> On Oct 23, 2017, at 5:22 PM, Max Moiseev <mois...@apple.com >> <mailto:mois...@apple.com>> wrote: >> >>> It occurred to me that filteringMap(_:) should be even more descriptive, >>> still conform to the guidelines, although similarly unprecedented and >>> un-googlable. >>> >>> Max >>> >>>> On Oct 23, 2017, at 3:52 PM, Xiaodi Wu <xiaodi...@gmail.com >>>> <mailto:xiaodi...@gmail.com>> wrote: >>>> >>>> +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. >>>> On Mon, Oct 23, 2017 at 17:24 BJ Homer via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> 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. >>>> >>>> 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. >>>> >>>> So yes, a big +1 from me. Thanks! >>>> >>>> -BJ Homer >>>> >>>>> On Oct 23, 2017, at 4:15 PM, Max Moiseev via swift-evolution >>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>> >>>>> Hi swift-evolution! >>>>> >>>>> I would like to propose the following change to the standard library: >>>>> >>>>> deprecate `Sequence.flatMap<U>(_: (Element) -> U?) -> [U]` and make this >>>>> functionality available under a new name `Sequence.filteredMap(_:)`. >>>>> >>>>> The draft is available at >>>>> https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95 >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95> and is >>>>> included below for your convenience. >>>>> >>>>> Max >>>>> >>>>> Introduce Sequence.filteredMap(_:) >>>>> >>>>> Proposal: SE-NNNN <https://gist.github.com/moiseev/NNNN-filename.md> >>>>> Authors: Max Moiseev <https://github.com/moiseev> >>>>> Review Manager: TBD >>>>> Status: Awaiting implementation >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#introduction>Introduction >>>>> >>>>> We propose to deprecate the controversial version of a Sequence.flatMap >>>>> method and provide the same functionality under a different, and >>>>> potentially more descriptive, name. >>>>> >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#motivation>Motivation >>>>> >>>>> The Swift standard library currently defines 3 distinct overloads for >>>>> flatMap: >>>>> >>>>> Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element] >>>>> where S : Sequence >>>>> Optional.flatMap<U>(_: (Wrapped) -> U?) -> U? >>>>> Sequence.flatMap<U>(_: (Element) -> U?) -> [U] >>>>> The last one, despite being useful in certain situations, can be (and >>>>> often is) misused. Consider the following snippet: >>>>> >>>>> struct Person { >>>>> var age: Int >>>>> var name: String >>>>> } >>>>> >>>>> func getAges(people: [Person]) -> [Int] { >>>>> return people.flatMap { $0.age } >>>>> } >>>>> What happens inside getNames is: thanks to the implicit promotion to >>>>> Optional, the result of the closure gets wrapped into a .some, then >>>>> immediately unwrapped by the implementation of flatMap, and appended to >>>>> the result array. All this unnecessary wrapping and unwrapping can be >>>>> easily avoided by just using map instead. >>>>> >>>>> func getAges(people: [Person]) -> [Int] { >>>>> return people.map { $0.age } >>>>> } >>>>> It gets even worse when we consider future code modifications, like the >>>>> one where Swift 4 introduced a Stringconformance to the Collection >>>>> protocol. The following code used to compile (due to the flatMap overload >>>>> in question). >>>>> >>>>> func getNames(people: [Person]) -> [String] { >>>>> return people.flatMap { $0.name } >>>>> } >>>>> 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 flatMap >>>>> is used. Imagine however if it was just a let names = people.flatMap { >>>>> $0.name <http://0.name/> } statement, and the names variable were used >>>>> elsewhere. The compiler error would be misleading. >>>>> >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#proposed-solution>Proposed >>>>> solution >>>>> >>>>> We propose to deprecate the controversial overload of flatMap and >>>>> re-introduce the same functionality under a new name. The name being >>>>> filteredMap(_:) as we believe it best describes the intent of this >>>>> function. >>>>> >>>>> For reference, here are the alternative names from other languages: >>>>> >>>>> Haskell, Idris >>>>> mapMaybe :: (a -> Maybe b) -> [a] -> [b] >>>>> Ocaml (Core and Batteries) >>>>> filter_map : 'a t -> f:('a -> 'b >>>>> option) -> 'b t >>>>> F# >>>>> List.choose : ('T -> 'U option) -> 'T list -> 'U list >>>>> Rust >>>>> fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> >>>>> >>>>> where F: FnMut(Self::Item) -> Option<B> >>>>> Scala >>>>> def collect[B](pf: PartialFunction[A, B]): List[B] >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#source-compatibility>Source >>>>> compatibility >>>>> >>>>> Since the old function will still be available (although deprecated) all >>>>> the existing code will compile, producing a deprecation warning and a >>>>> fix-it. >>>>> >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#effect-on-abi-stability>Effect >>>>> on ABI stability >>>>> >>>>> This is an additive API change, and does not affect ABI stability. >>>>> >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#effect-on-api-resilience>Effect >>>>> on API resilience >>>>> >>>>> Ideally, the deprecated flatMap 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. >>>>> >>>>> >>>>> <https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95#alternatives-considered>Alternatives >>>>> considered >>>>> >>>>> 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 Any). >>>>> >>>>> The following alternative names for this function were considered: >>>>> >>>>> mapNonNil(_:) >>>>> Does not communicate what happens to nil’s >>>>> mapSome(_:) >>>>> Reads more like «map some elements of the sequence, >>>>> but not the others» rather than «process only the ones that produce an >>>>> Optional.some» >>>>> filterMap(_:) >>>>> Does not really follow the naming guidelines and >>>>> doesn’t seem to be common enough to be considered a term of art. >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution