I also cast my vote for filterMap. It’s concise, understandable and is kind of 
a term of art also.

> On 24 Oct 2017, at 02:56, BJ Homer via swift-evolution 
> <[email protected]> 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 <[email protected] 
> <mailto:[email protected]>> 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 <[email protected] 
>>> <mailto:[email protected]>> 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 
>>> <[email protected] <mailto:[email protected]>> 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 
>>>> <[email protected] <mailto:[email protected]>> 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
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to