[swift-evolution] [SHORT Review] SE-0133: Rename `flatten()` to `joined()`

Dave Abrahams dabrahams at apple.com
Mon Jul 25 17:36:45 CDT 2016


on Mon Jul 25 2016, Jacob Bandes-Storch <jtbandes-AT-gmail.com> wrote:

> On Mon, Jul 25, 2016 at 1:11 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> I'm giving the overall idea a +0 and the specific proposal as currently
>> written a -1, because I think this is a much more complicated bikeshed
>> than it appears to be on the surface and the proposal doesn't begin to
>> address the issues.  Specifically, I'm concerned about these points:
>>
>> * `flatten` works on Optional<Optional<T>> and sequences of Optional<T>.
>>   How does it make sense to rename these operations “join?”
>>
>
> Does it really? These don't work for me:
>
> let x = [1,2,nil,4]
> x.flatten()
>
> let y = Optional(Optional(42))
> y.flatten()

Agh.  Well, hello, bug!  It's supposed to, IMO, for the same reason that
flatMap does.  The relationship is that 

  x.flatten() === x.flatMap {$0}

So how would you document the semantics of 

   Optional(Optional(42)).joined()

>> * The name and semantics of `flatten` is linked to that of `flatMap`.
>>   It's almost impossible to explain what `flatMap` does without
>>   reference to `flatten`.  Will it make sense to explain `flatMap` in
>>   terms of `joined`?
>>
>
> I think the current documentation comments do a pretty good job:
>
> On the [T].flatMap(T -> U?) -> [U] version:
>   /// Returns an array containing the non-`nil` results of calling the given
>   /// transformation with each element of this sequence.
>
> On the [T].flatMap(T -> [U]) -> [U] version:
>   /// Returns an array containing the concatenated results of calling the
>   /// given transformation with each element of this sequence.
>
> (This one also mentions array.map(transform).flatten(), which would become
> array.map(transform).joined().)

Okay.

>> * `flatten` is a functional term of art in the same family as `flatMap`.
>>   We have good reasons to consider changing some of the other names in
>>   this family, such as `filter` and `reduce`, but that idea has met with
>>   significant resistance on the list.  How far should we go?  Does it
>>   make sense to make this one change alone?
>
> I wouldn't argue for renaming flatMap. I'm not suggesting to change the
> name of flatten() because I don't like it (I do); I'm suggesting to change
> it because — unlike Ruby, whose Array has #flatten and #join, but the
> latter is *only* for producing strings — we seem to have the *same*
> functionality behind 2 differently-named APIs.
>
> (Actually I feel like flatMap is a more fundamental functional method in
> the family of filter and reduce than flatten/joined is. flatten is just
> flatMap({$0}), 

x.map(f) can be written as x.flatMap(Optional(f)) or even x.flatMap(f)
for that matter.  Does that make flatMap more fundamental than map? ;-)

Something roughly like this holds:

  flatMap = map • flatten
  map = flatMap • Optional
  flatten = flatMap • identity

-- 
Dave


More information about the swift-evolution mailing list