Well, I have no problems with `flatMap` but then I am used to Monads.
I would not rename that overload if there is any hope that we might get Monads 
sometime in the future but probably there is none (which is sad).

So I would suggest `mapDroppingNil` or maybe `mapRejectingNil`.

-Thorsten


> Am 24.10.2017 um 05:38 schrieb Howard Lovatt via swift-evolution 
> <[email protected]>:
> 
> +1 good idea.
> 
> Re. the naming I would suggest `mapFilterNil` since it says what it does and 
> filter, nil, and map are all understood already in Swift. (I have sympathy 
> for people wanting `mapFilteringNil`, but Swift chose `filter`.)
> 
> The problems I see with `filterMap` are that:
> 
>   1. It sounds like it is a merged `filter` and `map` and therefore you would 
> expect it to have two arguments, one to filter and one to map, i.e. 
> `filterMap<R>(filter: (T) -> Bool, map: (T) -> R) -> [R]`.
>   2. It sounds like it will filter the incoming values (for `nil`, but see 1 
> above) and then map, i.e. `filterMap<R>(map: (T?) -> R) -> [R]`, note `T?` 
> *not* `R?`.
> 
>   -- Howard.
> 
>> On 24 October 2017 at 11: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]> 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]> 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]> 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]> 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 and is 
>>>>>> included below for your convenience.
>>>>>> 
>>>>>> Max
>>>>>> 
>>>>>> Introduce Sequence.filteredMap(_:)
>>>>>> Proposal: SE-NNNN
>>>>>> Authors: Max Moiseev
>>>>>> Review Manager: TBD
>>>>>> Status: Awaiting implementation
>>>>>> 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.
>>>>>> 
>>>>>> 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 } statement, and the names variable were used elsewhere. The 
>>>>>> compiler error would be misleading.
>>>>>> 
>>>>>> 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]
>>>>>> 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.
>>>>>> 
>>>>>> Effect on ABI stability
>>>>>> 
>>>>>> This is an additive API change, and does not affect ABI stability.
>>>>>> 
>>>>>> 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.
>>>>>> 
>>>>>> 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]
>>>>>> 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
> 
> _______________________________________________
> 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