+1 from me as well.

——
Adrian Kashivskyy

On 24 Oct 2017, 00:24 +0200, 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

Reply via email to