Sorting Collections with `map` closures and SortDescriptors

  • I would want to see an overload like func their<Input, SortKey: Comparable>(_ sortKey: SortKey) -> (Input, Input) -> Bool that provides a sensible default for Comparable sort keys.

The challenge with providing an overload with a default second argument is the conflation of their with comparison functions specifically. Lifting a function of one argument onto a function of two arguments is a general operation without ties to concrete types. You can imagine something like the following for a single-argument their function:

sequenceOfUserTuples.map(their { $0.age })

I would expect an array of tuples containing the age corresponding to each user in each tuple of the previous sequence rather than an array of Bool values. This intuition would (to me) suggest a default argument of the identity function for the second parameter—and at that point we've just defined map on the homogeneous two-tuple.

I think a better spelling for a single-argument version of their specialized for comparison functions would be the lesser(of:) and greater(of:) functions that Ben described above.

  • There's precedent for this approach in Haskell, but that's a very composition-heavy language. Are there any examples of a composition-approach like this in the Standard Library?
  • I'm not a huge fan of free-floating global functions — they're tough to find if you don't already know about them.

I think their would be a great fit for a non-standard library geared toward functional utilities, but the non-standard library movement hasn't gained much traction. You're right that it doesn't align well with the Standard Library, which (at least thus far) hasn't supported abstractions at this level, which really only make sense as free functions—but I felt it was worth a mention in this thread for its applicability in this domain.

  • their({ $0.age }) isn't that much shorter than { $0.age < $1.age }

Jordan just touched on this, but the goal here isn't to reduce the number of characters; it's to reduce repetition. The arguments here aren't specific to their and can be made analagously to those proposed with Bool.toggle() with respect to the value of removing repetition on opposite sides of an operator.